@@ -242,22 +242,28 @@ public sealed override object VisitNotations(P.NotationsContext context)
242242 return true ;
243243 }
244244
245- private void WarnMoreThanOneTokens ( IList < IToken > ps )
245+ private void AlertExtraToken ( string extraStr )
246246 {
247- if ( ps . Count <= 1 ) return ;
248- var extraStr = "'" + string . Join ( "" , ps . Skip ( 1 ) . Select ( x => x . Text ) ) + "'" ;
247+ if ( extraStr . First ( ) != '\' ' ) extraStr = "'" + extraStr + "'" ;
249248 if ( StrictLevel == StrictLevelEnum . Strict )
250249 { // 严格模式,抛异常
251250 AddAlert ( Error , string . Format ( Locale . RecoverInlineExtraneousTokenStrict , extraStr ) ) ;
252251 throw new ConversionException ( alerts ) ;
253252 }
254253 else AddAlert ( Warning , string . Format ( Locale . RecoverInlineExtraneousToken , extraStr ) ) ;
255254 }
255+
256+ private void AlertIfMoreThanOneTokens ( IList < IToken > ps )
257+ {
258+ if ( ps . Count <= 1 ) return ;
259+ var extraStr = string . Join ( "" , ps . Skip ( 1 ) . Select ( x => x . Text ) ) ;
260+ AlertExtraToken ( extraStr ) ;
261+ }
256262
257- private void WarnMoreParentheses ( IList < IToken > lp , IList < IToken > rp )
263+ private void AlertIfMoreParentheses ( IList < IToken > lp , IList < IToken > rp )
258264 {
259- WarnMoreThanOneTokens ( lp ) ;
260- WarnMoreThanOneTokens ( rp ) ;
265+ AlertIfMoreThanOneTokens ( lp ) ;
266+ AlertIfMoreThanOneTokens ( rp ) ;
261267 }
262268
263269 public sealed override object VisitAbsulouteStepTag ( P . AbsulouteStepTagContext context )
@@ -269,7 +275,7 @@ public sealed override object VisitAbsulouteStepTag(P.AbsulouteStepTagContext co
269275 absoluteTimeStepWarned = true ;
270276 }
271277 currContext = context ;
272- WarnMoreParentheses ( context . _lp , context . _rp ) ;
278+ AlertIfMoreParentheses ( context . _lp , context . _rp ) ;
273279 absoluteTimeStep = ( decimal ) VisitNumber ( context . number ( ) ) ;
274280 var currentBpm = chart . BpmList . Last ( ) . Bpm ;
275281 step = ( Rational ) absoluteTimeStep / ( 240 / ( Rational ) currentBpm ) ;
@@ -280,7 +286,7 @@ public sealed override object VisitBpmTag(P.BpmTagContext context)
280286 {
281287 if ( SubtreeHasException ( context ) ) return false ; // 如果本节点下有异常,则直接整个吞掉,(避免具体的规则遇到不完整子树、爆出更不可预测的错误)
282288 currContext = context ;
283- WarnMoreParentheses ( context . _lp , context . _rp ) ;
289+ AlertIfMoreParentheses ( context . _lp , context . _rp ) ;
284290 var bpm = ( decimal ) VisitNumber ( context . number ( ) ) ;
285291 chart . BpmList . Add ( new BPM ( now , bpm ) ) ;
286292 if ( absoluteTimeStep != null )
@@ -294,7 +300,7 @@ public sealed override object VisitMetTag(P.MetTagContext context)
294300 { // metTag指的是标记分音的tag,如{4}
295301 if ( SubtreeHasException ( context ) ) return false ; // 如果本节点下有异常,则直接整个吞掉,(避免具体的规则遇到不完整子树、爆出更不可预测的错误)
296302 currContext = context ;
297- WarnMoreParentheses ( context . _lp , context . _rp ) ;
303+ AlertIfMoreParentheses ( context . _lp , context . _rp ) ;
298304 var quaver = int . Parse ( context . @int ( ) . GetText ( ) ) ;
299305 step = new Rational ( 1 , quaver ) ;
300306 absoluteTimeStep = null ;
@@ -313,28 +319,31 @@ public sealed override object VisitNoteGroup(P.NoteGroupContext context)
313319 else if ( child is P . EachNoteContext c2 )
314320 {
315321 noteC = c2 . note ( ) ;
316-
317- var separators = c2 . _sep ;
318- if ( separators . Count >= 2 && separators . All ( x=> x . Type == L . FALSE_EACH ) )
322+ if ( noteC == null )
319323 {
320- // 出现连续多个反引号的情况,如"2``3"。
321- // 这并不是标准的simai语法。但是,MajdataView中对此提供了支持,将每个`实现为128分音。
322- // 因此,我们也支持这一特性,在遇到大于一个`时,不实现成FalseEachIndex,而是直接给予相同的实现、每个`错后128分音。
323- var length = separators . Count * new Rational ( 1 , 128 ) ;
324- now = ( now + length ) . CanonicalForm ;
325- extendedFalseEach += length ;
326- falseEachIdx = 0 ;
327- if ( ! extendedFalseEachWarned )
328- {
329- AddAlert ( Warning , Locale . ExtenedFalseEach , context ) ;
330- extendedFalseEachWarned = true ;
331- }
324+ AlertExtraToken ( c2 . sep . Text ) ;
325+ continue ;
332326 }
333- else
327+ if ( c2 . sep . Type == L . FALSE_EACH )
334328 {
335- WarnMoreThanOneTokens ( separators ) ;
336- if ( separators [ 0 ] . Type == L . FALSE_EACH ) falseEachIdx ++ ;
329+ if ( c2 . sep . Text . Length >= 2 )
330+ {
331+ // 出现连续多个反引号的情况,如"2``3"。
332+ // 这并不是标准的simai语法。但是,MajdataView中对此提供了支持,将每个`实现为128分音。
333+ // 因此,我们也支持这一特性,在遇到大于一个`时,不实现成FalseEachIndex,而是直接给予相同的实现、每个`错后128分音。
334+ var length = c2 . sep . Text . Length * new Rational ( 1 , 128 ) ;
335+ now = ( now + length ) . CanonicalForm ;
336+ extendedFalseEach += length ;
337+ falseEachIdx = 0 ;
338+ if ( ! extendedFalseEachWarned )
339+ {
340+ AddAlert ( Warning , Locale . ExtenedFalseEach , context ) ;
341+ extendedFalseEachWarned = true ;
342+ }
343+ }
344+ else falseEachIdx ++ ; // 普通的伪双押
337345 }
346+ // else 是普通双押符号'/'。无需做任何特殊处理,正常解析noteContext就好。
338347 }
339348 else throw Utils . Fail ( ) ;
340349
@@ -459,7 +468,7 @@ public sealed override object VisitDuration(P.DurationContext? context)
459468 result . InvariantBar = 0 ;
460469 return result ;
461470 }
462- WarnMoreParentheses ( context . _lp , context . _rp ) ;
471+ AlertIfMoreParentheses ( context . _lp , context . _rp ) ;
463472 if ( context . beats ( ) != null ) result . InvariantBar = ( Rational ) VisitBeats ( context . beats ( ) ) ;
464473 else result . Seconds = ( Rational ) ( decimal ) VisitNumber ( context . number ( ) ) ;
465474 return result ;
@@ -505,7 +514,7 @@ public sealed override object VisitSlideDuration(P.SlideDurationContext context)
505514 var result = new Duration ( currNote ! ) ;
506515 Duration ? waitTime = null ;
507516 isRealExactWaitTime = false ;
508- WarnMoreParentheses ( context . _lp , context . _rp ) ;
517+ AlertIfMoreParentheses ( context . _lp , context . _rp ) ;
509518
510519 if ( context . waitTime ( ) != null )
511520 {
0 commit comments