Antlr v4:什么';这个简单的C#文字语法错了

本文关键字:简单 文字 错了 语法 v4 什么 Antlr | 更新日期: 2023-09-27 18:24:57

我决定将C#官方语法翻译为antlr v4。然而,在测试时,我遇到了以下问题。给定的语法与像'n'ntrue'n'n<EOF>这样的简单单词不匹配。它一直在说mismatched input ''n'ntrue'n'n' expecting Literal 。即使在我将Literal的定义保留为Literal: BooleanLiteral;之后,输入'n'ntrue'n'n<EOF>仍然不匹配。我本以为语法会跳过'n,而不是true<EOF>,但显然这并没有发生。尝试过调试,但仍然找不到任何错误。有什么想法吗?

grammar Test;
start: Literal EOF;
/**********
 *
 * Literals
 *
 **********/
Literal
    :   BooleanLiteral 
    |   IntegerLiteral 
    |   RealLiteral 
    |   CharacterLiteral 
    |   StringLiteral 
    |   NullLiteral 
    ;
BooleanLiteral
    :   'true' 
    |   'false' 
    ;
IntegerLiteral
    :   DecimalIntegerLiteral 
    |   HexadecimalIntegerLiteral 
    ;
DecimalIntegerLiteral
    :   DecimalDigits IntegerTypeSuffix? 
    ;
DecimalDigits
    :   DecimalDigit+
    ;
DecimalDigit
    :   [0-9]
    ;
IntegerTypeSuffix
    :   'U' 
    |   'u' 
    |   'L' 
    |   'l' 
    |   'UL' 
    |   'Ul' 
    |   'uL' 
    |   'ul' 
    |   'LU' 
    |   'Lu' 
    |   'lU' 
    |   'lu' 
    ;
HexadecimalIntegerLiteral
    :   ('0x' | '0X') HexDigits IntegerTypeSuffix?
    ;
HexDigits
    :   HexDigit+
    ;
HexDigit    
    :   [0-9A-Fa-f]
    ;
RealLiteral
    :   DecimalDigits '.' DecimalDigits ExponentPart? RealTypeSuffix? 
    |   '.' DecimalDigits ExponentPart? RealTypeSuffix? 
    |   DecimalDigits ExponentPart RealTypeSuffix? 
    |   DecimalDigits RealTypeSuffix 
    ;
ExponentPart
    :   ('e' | 'E') Sign? DecimalDigits
    ;
Sign    
    :   '+'
    |   '-' 
    ;
RealTypeSuffix  
    :   'F'
    |   'f' 
    |   'D' 
    |   'd' 
    |   'M' 
    |   'm' 
    ;
CharacterLiteral
    :   '''' Character '''' 
    ;
Character
    :   SingleCharacter 
    |   SimpleEscapeSequence 
    |   HexadecimalEscapeSequence 
    |   UnicodeEscapeSequence 
    ;
UnicodeEscapeSequence
    :   '''' 'u' HexDigit HexDigit HexDigit HexDigit 
    |   '''' 'U' HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit HexDigit 
    ;
SingleCharacter
    :   ~['''''''u000D'u000A'u0085'u2028'u2029]
    ;
SimpleEscapeSequence    
    : ''''''
    | '''"'
    | ''''''
    | '''0'
    | '''a'
    | '''b'
    | '''f'
    | '''n'
    | '''r'
    | '''t'
    | '''v'
    ;
HexadecimalEscapeSequence
    :   '''x' HexDigit HexDigit? HexDigit? HexDigit? 
    ;
StringLiteral
    :   RegularStringLiteral 
    |   VerbatimStringLiteral 
    ;
RegularStringLiteral
    :   '"' RegularStringLiteralCharacters? '"' 
    ;
RegularStringLiteralCharacters
    :   RegularStringLiteralCharacter+
    ;
RegularStringLiteralCharacter
    :   SingleRegularStringLiteralCharacter 
    |   SimpleEscapeSequence 
    |   HexadecimalEscapeSequence 
    |   UnicodeEscapeSequence 
    ;
SingleRegularStringLiteralCharacter
    :   ~["'''u000D'u000A'u0085'u2028'u2029]
    ;
VerbatimStringLiteral
    :   '@"' VerbatimStringLiteralCharacters? '"' 
    ;
VerbatimStringLiteralCharacters
    :   VerbatimStringLiteralCharacter+
    ;
VerbatimStringLiteralCharacter
    :   SingleVerbatimStringLiteralCharacter 
    |   QuoteEscapeSequence 
    ;
SingleVerbatimStringLiteralCharacter
    :   ~["]
    ;
QuoteEscapeSequence
    :   '""' 
    ;
NullLiteral
    :   'null'
    ;

/**********
 *
 * Whitespaces and comments
 *
 **********/    
WS  : [ 't'r'n]+ -> skip
    ;
COMMENT
    :   '/*' .*? '*/' -> skip
    ;
LINE_COMMENT
    :   '//' ~['r'n]* -> skip
    ;

编辑:好的,我已经设法将问题隔离到这段代码中:

grammar Test;
start : VerbatimStringLiteral EOF ;
VerbatimStringLiteral
    :   '@"' VerbatimStringLiteralCharacter* '"' 
    ;
VerbatimStringLiteralCharacter
    :   SingleVerbatimStringLiteralCharacter 
    |   QuoteEscapeSequence 
    ;
SingleVerbatimStringLiteralCharacter
    :   ~["]
    ;
QuoteEscapeSequence
    :   '""' 
    ;
WS  :  [ 't'r'n]+ -> skip
    ;

Antlr v4:什么';这个简单的C#文字语法错了

Lexer规则本身不产生令牌,应使用fragment修饰符进行标记。例如,QuoteEscapeSequence不是一个独立的令牌;它只是VerbatimStringLiteral令牌的一部分,所以应该用fragment标记它。以下是一些其他规则,应该是fragment规则:

  • VerbatimStringLiteralCharacter
  • SingleVerbatimStringLiteralCharacter
  • SingleRegularStringLiteralCharacter
  • RegularStringLiteralCharacter
  • RegularStringLiteralCharacters&lar;这个是您在这个特定输入中的错误来源
  • SimpleEscapeSequence

可能还有更多,但这应该会让你知道问题是什么以及如何解决它。