0

我决定将 C# 官方语法翻译成antlr v4。但是,在测试时我遇到了以下问题。给定的语法与简单的单词不匹配,例如\n\ntrue\n\n<EOF>. 它一直在说mismatched input '\n\ntrue\n\n' expecting Literal 。即使在我离开Literalas的定义后,Literal: BooleanLiteral;输入\n\ntrue\n\n<EOF>仍然不匹配。我期待语法跳过\ns comsume the trueand<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
    ;
4

1 回答 1

1

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

  • VerbatimStringLiteralCharacter
  • SingleVerbatimStringLiteralCharacter
  • SingleRegularStringLiteralCharacter
  • RegularStringLiteralCharacter
  • RegularStringLiteralCharacters← 这个是你对这个特定输入的错误的来源
  • SimpleEscapeSequence

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

于 2013-07-26T11:31:13.253 回答