Skip to content

Commit c992f7b

Browse files
committed
enhance: 通过适当抽提文法,增强lax模式下的错误修复
1 parent bcb5b88 commit c992f7b

3 files changed

Lines changed: 23 additions & 12 deletions

File tree

parser/mai/Simai.g4

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ modifiers: (MODIFIER | TAP_TO_STAR | STAR_TO_TAP | NO_STAR)*;
4040
// 语法
4141
// ---------------------------------------------------------------------------
4242

43-
chart: (notations COMMA)* CHART_END? EOF;
43+
chart: notationsAndComma* CHART_END? EOF;
44+
notationsAndComma: notations COMMA; // 之所以要拆开写,是为了解决Lax模式下,一个notation崩掉,异常栈直接跳回chart()层造成整个解析停止的问题
4445

4546
// 同一时刻的所有标记,包括note标记、bpm标记等等
4647
notations: (bpmTag | absulouteStepTag | metTag)* noteGroup?;
@@ -80,7 +81,7 @@ asBpm: number;
8081
slide: tap slideBody;
8182
sharedHeadSlide: '*' slideBody;
8283

83-
slideBody // 根据Simai文档规定,分为两种情况
84-
: slideType KEY (slideType KEY)* modifiers slideDuration modifiers // 只有最后一段星星有时间指定
85-
| slideType KEY (slideDuration slideType KEY)* modifiers slideDuration modifiers // 每一段星星都有独立的时间指定
86-
;
84+
slideBody: slideType KEY ( // 接下来的部分,根据Simai文档规定,分为两种情况
85+
(slideType KEY)* // 只有最后一段星星有时间指定
86+
| (slideDuration slideType KEY)* // 每一段星星都有独立的时间指定
87+
) modifiers slideDuration modifiers;

parser/mai/SimaiParser.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,16 +182,20 @@ private IAntlrErrorStrategy ErrorStrategy()
182182

183183
public sealed override object VisitChart(P.ChartContext context)
184184
{
185-
foreach (var notations in context.notations())
185+
foreach (var item in context.notationsAndComma())
186186
{
187-
VisitNotations(notations);
187+
VisitNotations(item.notations());
188188
if (chart.BpmList.Count == 0) AddDefaultBpm();
189-
if (extendedFalseEach > 0)
190-
{ // 如果之前的解析过程中,触发了extendedFalseEach的话。则要把被额外增加的时间扣回来。
191-
now -= extendedFalseEach;
192-
extendedFalseEach = 0;
189+
if (item.COMMA() != null)
190+
{ // 根据notationsAndComma的定义,正常情况下一定是有逗号的。因此万一没有逗号,那就是lax模式错误恢复的结果。
191+
// 此时,时间轴不应自增,以确保整个谱面的时间轴仍然大部分准确。
192+
if (extendedFalseEach > 0)
193+
{ // 如果之前的解析过程中,触发了extendedFalseEach的话。则要把被额外增加的时间扣回来。
194+
now -= extendedFalseEach;
195+
extendedFalseEach = 0;
196+
}
197+
now = (now + step).CanonicalForm;
193198
}
194-
now = (now + step).CanonicalForm;
195199
}
196200
return true;
197201
}

tests/mai/Simai纠错测试.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,12 @@ public static IEnumerable<object[]> Lax_Scratch_Cases()
286286
"(120){4}1,,3,4-5[6:1],7,8,E",
287287
"(120){4}1,2h[3:,3,4-5[6:1],7,8,E"
288288
];
289+
yield return
290+
[
291+
"双中括号 '[]'",
292+
"(120){4}1,2,3,",
293+
"(120){4}1[],2,3,"
294+
];
289295
}
290296

291297
public static IEnumerable<object[]> 多余修饰符_Cases()

0 commit comments

Comments
 (0)