Skip to content

Commit 6ce6a44

Browse files
committed
[+] 基于ErrorStrategy,对[8-1]做错误处理
1 parent 39b33fc commit 6ce6a44

8 files changed

Lines changed: 114 additions & 7 deletions

File tree

i18n/Locale.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

i18n/Locale.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,7 @@
205205
<data name="LaxTryfixReminder" xml:space="preserve">
206206
<value>. The affected note(s) was discarded.</value>
207207
</data>
208+
<data name="Fixed" xml:space="preserve">
209+
<value>. Fixed automatically.</value>
210+
</data>
208211
</root>

i18n/Locale.zh-hans.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,7 @@
205205
<data name="LaxTryfixReminder" xml:space="preserve">
206206
<value>。出问题的音符已被丢弃。</value>
207207
</data>
208+
<data name="Fixed" xml:space="preserve">
209+
<value>。已自动为您修复。</value>
210+
</data>
208211
</root>

i18n/Locale.zh-hant.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,7 @@
205205
<data name="LaxTryfixReminder" xml:space="preserve">
206206
<value>。出問題的音符已被捨棄。</value>
207207
</data>
208+
<data name="Fixed" xml:space="preserve">
209+
<value>。已自動為您修復。</value>
210+
</data>
208211
</root>

parser/simai/ErrorStrategy.cs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using MuConvert.utils;
55
using static MuConvert.utils.Alert.LEVEL;
66
using L = MuConvert.Antlr.SimaiLexer;
7+
using P = MuConvert.Antlr.SimaiParser;
78

89
namespace MuConvert.parser.simai;
910

@@ -152,6 +153,8 @@ protected override void ReportMissingToken(Parser recognizer)
152153

153154
public override void Recover(Parser recognizer, RecognitionException e)
154155
{
156+
if (SpecificRecover((P)recognizer, e)) return; // 是特定类型的错误、已通过SpecificRecover修复完成
157+
155158
if (this.lastErrorIndex == recognizer.InputStream.Index && this.lastErrorStates != null && this.lastErrorStates.Contains(recognizer.State))
156159
recognizer.Consume();
157160
this.lastErrorIndex = recognizer.InputStream.Index;
@@ -165,6 +168,48 @@ public override void Recover(Parser recognizer, RecognitionException e)
165168

166169
this.ConsumeUntil(recognizer, errorRecoverySet);
167170
}
171+
172+
/**
173+
* 尝试修复一些特定类型的错误。
174+
* - beats中,':'误打为'-'
175+
*/
176+
protected virtual bool SpecificRecover(P parser, RecognitionException e)
177+
{
178+
var ctx = parser.Context;
179+
var rule = ctx.RuleIndex;
180+
if (rule == P.RULE_beats && e is InputMismatchException &&
181+
e.OffendingToken.Text == "-" && e.GetExpectedTokens().Contains(_literals[":"]))
182+
{ // [4:1]中,错把:打成-了
183+
simaiParser.alerts.Last().Level = Warning; // Error改为Warning,因为恢复了
184+
simaiParser.alerts.Last().Description += Locale.Fixed;
185+
parser.Match(L.SLIDE_TYPE);
186+
ctx.exception = null;
187+
parser.@int();
188+
return true;
189+
}
190+
return false;
191+
}
192+
193+
/**
194+
* 重新执行func对应的解析函数,并把结果合并进oldContext。
195+
*/
196+
protected void Rerun<T>(P parser, Func<T> func, T oldContext) where T : ParserRuleContext
197+
{
198+
// 缓存全局变量,便于稍后恢复现场
199+
var savedState = parser.State;
200+
var savedContext = parser.Context;
201+
// 设置现场为父级的状态,从而为再次调用解析函数做好准备
202+
parser.State = oldContext.invokingState;
203+
parser.Context = (ParserRuleContext)oldContext.Parent;
204+
// 再次调用解析函数,得到的结果(子节点)合并进oldContext、新节点删除之
205+
var newContext = func();
206+
parser.Context?.RemoveLastChild(); // func返回时会调用ExitRule,从而context还是oldContext.Parent不变,直接RemoveLastChild()即可移除newContext
207+
oldContext.children = oldContext.children.Concat(newContext.children).ToList();
208+
oldContext.exception = null;
209+
// 恢复现场
210+
parser.State = savedState;
211+
parser.Context = savedContext;
212+
}
168213
}
169214

170215
/**
@@ -174,5 +219,9 @@ public class ModerateErrorStrategy(SimaiParser simaiParser) : LaxErrorStrategy(s
174219
{
175220
private BailErrorStrategy _bail = new();
176221

177-
public override void Recover(Parser recognizer, RecognitionException e) => _bail.Recover(recognizer, e); // 不准recover,只准recoverInline
222+
public override void Recover(Parser recognizer, RecognitionException e)
223+
{
224+
if (SpecificRecover((P)recognizer, e)) return; // 是特定类型的错误、已通过SpecificRecover修复完成,则ok
225+
_bail.Recover(recognizer, e); // 否则,不准recover(通过bail strategy的recover方法来抛异常),只准recoverInline
226+
}
178227
}

parser/simai/Simai.g4

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ STAR_TO_TAP: '@';
2121
NO_STAR: '?' | '!';
2222

2323
KEY: [1-8];
24-
SLIDE_TYPE: '-' | 'v' | '<' | '>' | '^' | 'p' | 'q' | 'pp' | 'qq' | 's' | 'z' | 'w' | 'V' KEY; // 只有V后面需要多跟一个键位号
2524
TOUCH_AREA: 'A' [1-8] | 'B' [1-8] | 'C' [1-2]? | 'D' [1-8] | 'E' [1-8];
25+
26+
SLIDE_TYPE: '-' | 'v' | '<' | '>' | '^' | 'p' | 'q' | 'pp' | 'qq' | 's' | 'z' | 'w' | 'V' KEY; // 只有V后面需要多跟一个键位号
27+
slideType: SLIDE_TYPE;
28+
2629
INT: [0-9];
2730

2831
int: (KEY | INT)+;
@@ -77,10 +80,8 @@ asBpm: number;
7780

7881
slide: tap slideBody;
7982
sharedHeadSlide: '*' slideBody;
80-
83+
8184
slideBody // 根据Simai文档规定,分为两种情况
82-
: (slideType KEY)* slideType KEY modifiers slideDuration modifiers // 只有最后一段星星有时间指定
83-
| (slideType KEY slideDuration)* slideType KEY modifiers slideDuration modifiers // 每一段星星都有独立的时间指定
85+
: slideType KEY (slideType KEY)* modifiers slideDuration modifiers // 只有最后一段星星有时间指定
86+
| slideType KEY (slideDuration slideType KEY)* modifiers slideDuration modifiers // 每一段星星都有独立的时间指定
8487
;
85-
86-
slideType: SLIDE_TYPE;

tests/Simai预处理纠错测试.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ public static IEnumerable<object[]> TryFix_Cases()
9191
"(120){4}1?-3[1:1],E",
9292
"(120){4}1-?3[1:1],E"
9393
];
94+
95+
yield return
96+
[
97+
"多打了一个双押符号",
98+
"(120){4}1//2,2//3,4,E",
99+
"(120){4}1/2,2//3,4,E"
100+
];
94101
}
95102

96103
public static IEnumerable<object[]> Comment_Cases()
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
simai: |
2+
(120){{16}}1,((180))2,2h[16-2],
3+
3-4[[4:1]],5-6[[#0.1]],
4+
3h[[4:1]],5h[[#0.1]],B2h[[4:1]],Ch[[#0.1]],
5+
3-4[[4:1]]/5-6[[#0.1]],
6+
3h[[4:1]]/5h[[#0.1]],
7+
3-4[[4:1]]*-6[[#0.1]],
8+
1-?2[8:1]b,3-@bx4b[8:1],E
9+
ma2: |
10+
NMTAP 0 0 0
11+
NMTAP 0 24 1
12+
NMHLD 0 48 1 48
13+
NMSTR 0 72 2
14+
NMSI_ 0 72 2 96 96 3
15+
NMSTR 0 96 4
16+
NMSI_ 0 96 4 96 29 5
17+
NMHLD 0 120 2 96
18+
NMHLD 0 144 4 29
19+
NMTHO 0 168 1 96 B 0 M1
20+
NMTHO 0 192 0 29 C 0 M1
21+
NMSTR 0 216 2
22+
NMSI_ 0 216 2 96 96 3
23+
NMSTR 0 216 4
24+
NMSI_ 0 216 4 96 29 5
25+
NMHLD 0 240 2 96
26+
NMHLD 0 240 4 29
27+
NMSTR 0 264 2
28+
NMSI_ 0 264 2 96 96 3
29+
NMSI_ 0 264 2 96 29 5
30+
BRSI_ 0 288 0 96 48 1
31+
BXTAP 0 312 2
32+
BRSI_ 0 312 2 96 48 3

0 commit comments

Comments
 (0)