Skip to content

Commit bcb5b88

Browse files
committed
fix: 修复由 946ea71 引起的一个测试回归性问题。
1 parent 946ea71 commit bcb5b88

2 files changed

Lines changed: 16 additions & 5 deletions

File tree

parser/mai/ErrorStrategy.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,15 @@ public void SyntaxError(TextWriter output, IRecognizer recognizer, int offending
8686
// 从offendingSymbol的位置向前、后分别找边界(逗号、双押/、伪双`),取中间的内容作为relevantNote
8787
int left = i-1, right = i+1;
8888
string RegionText() => stream.GetText(new Interval(left + 1, right - 1));
89-
bool IsBoundary(int type) => type == L.COMMA || type == L.FALSE_EACH || type == Utils.TokenType("/");
9089

91-
while (left >= 0 && !IsBoundary(stream.Get(left).Type)) left--;
90+
while (left >= 0 && !Utils.IsBoundaryToken(stream.Get(left).Type)) left--;
9291
while (left >= 0 || right < stream.Size) // 防止两边都到头了之后,死循环
9392
{
94-
while (right < stream.Size && !IsBoundary(stream.Get(right).Type)) right++;
93+
while (right < stream.Size && !Utils.IsBoundaryToken(stream.Get(right).Type)) right++;
9594
if (RegionText().Length > 5) break; // 相关区域中至少应该大于5个字符,否则不准break
9695
else if (left >= 0) left--; // 此时应强制left向左动一格,再继续向左找逗号
9796

98-
while (left >= 0 && !IsBoundary(stream.Get(left).Type)) left--;
97+
while (left >= 0 && !Utils.IsBoundaryToken(stream.Get(left).Type)) left--;
9998
if (RegionText().Length > 5) break;
10099
else if (right < stream.Size) right++;
101100
}
@@ -286,7 +285,17 @@ public override int AdaptivePredict(ITokenStream input, int decision, ParserRule
286285
// (不然的话,如果是tap则是逗号,如果是slide则是'-'等星星类型符号,如果是'h'则是正常没有缺少'h'的hold。这些情况都不需要特殊处理,正常走原逻辑即可。)
287286
if (tk == Utils.TokenType("["))
288287
{
289-
return la == P.TOUCH_AREA ? 6 : 4; // 6是touch hold,4是hold
288+
// 查看后面的所有token,只有形如一个完整的duration中括号序列的情况,才算是按照hold处理。
289+
bool t = false;
290+
for (i++; !Utils.IsBoundaryToken(input.LA(i)); i++)
291+
{
292+
if (!t && (input.LA(i) == Utils.TokenType(":") || input.LA(i) == Utils.TokenType("#"))) t = true;
293+
else if (t && input.LA(i) == Utils.TokenType("]"))
294+
{ // 在一开始的[之后,陆续匹配到了:或#,然后匹配到了],说明是一个完整的duration中括号序列。
295+
// 只有在此时,才强行修正分支预测的结果。
296+
return la == P.TOUCH_AREA ? 6 : 4; // 6是touch hold,4是hold
297+
}
298+
}
290299
}
291300
}
292301

utils/Utils.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ internal static Exception Fail(string msg = "")
4040
internal static int TokenType(string str) => _simaiLexerMap[str];
4141

4242
internal static bool IsModifier(int tokenType) => tokenType is L.MODIFIER or L.TAP_TO_STAR or L.STAR_TO_TAP or L.NO_STAR;
43+
44+
internal static bool IsBoundaryToken(int type) => type is L.COMMA or L.FALSE_EACH or L.CHART_END || type == TokenType("/");
4345

4446
public static (int, int) BarAndTick(Rational time, int resolution, int extraTicks = 0)
4547
{

0 commit comments

Comments
 (0)