Antlr4 语法问题(不完全解析)



我是ANTLR的新手,我正在尝试让这个语法工作:

grammar TemplateGrammar;
//Parser Rules 
start
    : block
    | statement
    | expression
    | parExpression
    | primary
    ;
block
    : LBRACE statement* RBRACE
    ;
statement
    : block
    | IF parExpression statement (ELSE statement)?
    | expression
    ;
parExpression
    : LPAREN expression RPAREN
    ;
expression
    : primary #PRIMARY
    | number op=('*'|'/') number            #MULDIV
    | number op=('+'|'-') number            #ADDSUB
    | number op=('>='|'<='|'>'|'<') number  #GRLWOREQUALS
    | expression op=('='|'!=') expression   #EQDIFF
    ;
primary
    :   parExpression
    |   literal
    ;
literal
    :   number  #NumberLiteral
    |   string  #StringLiteral
    |   columnName #ColumnNameLiteral
    ;
number
    :   DecimalIntegerLiteral       #DecimalIntegerLiteral
    |   DecimalFloatingPointLiteral #FloatLiteral
    ;
string
    :   '"' StringChars? '"'
    ;
columnName
    :   '[' StringChars? ']'
    ;
// Lexer Rules
//Integers
 DecimalIntegerLiteral
    :   DecimalNumeral
    ;
 fragment
 DecimalNumeral
    :   '0'
    |   NonZeroDigit (Digits? | Underscores Digits)
    ;
 fragment
 Digits
    :   Digit (DigitOrUnderscore* Digit)?
    ;
 fragment
 Digit
    :   '0'
    |   NonZeroDigit
    ;
 fragment
 NonZeroDigit
    :   [1-9]
    ;
 fragment
 DigitOrUnderscore
    :   Digit
    |   '_'
    ;
 fragment
 Underscores
    :   '_'+
    ;
//Floating point
DecimalFloatingPointLiteral
    :   Digits '.' Digits? ExponentPart?
    |   '.' Digits ExponentPart?
    |   Digits ExponentPart
    |   Digits
    ;
fragment
ExponentPart
    :   ExponentIndicator SignedInteger
    ;
fragment
ExponentIndicator
    :   [eE]
    ;
fragment
SignedInteger
    :   Sign? Digits
    ;
fragment
Sign
    :   [+-]
    ;
//Strings
StringChars
    :   StringChar+
    ;
fragment
StringChar
    :   ~["\]
    |   EscapeSequence
    ;
fragment
EscapeSequence
    :   '\' [btnfr"'\]
    ;
//Separators
LPAREN          : '(';
RPAREN          : ')';
LBRACE          : '{';
RBRACE          : '}';
LBRACK          : '[';
RBRACK          : ']';
COMMA           : ',';
DOT             : '.';
//Keywords
IF              : 'IF';
ELSE            : 'ELSE';
THEN            : 'THEN';
//Operators
PLUS            : '+';
MINUS           : '-';
MULTIPLY        : '*';
DIVIDE          : '/';
EQUALS          : '=';
DIFFERENT       : '!=';
GRTHAN          : '>';
GROREQUALS      : '>=';
LWTHAN          : '<';
LWOREQUALS      : '<=';
AND             : '&';
OR              : '|';
WHITESPACE : ( 't' | ' ' | 'r' | 'n'| 'u000C' )+ -> skip ;


当我"Test"输入时,它正在工作并返回字符串"Test".

以下是我在输入中输入"Test"时在IParseTree中得到的结果:

"(start (语句 (表达式 (primary (literal (string \" Test \")

)))))


但是当我输入[Test](几乎与"Test"相同,但用大括号而不是引号),解析器无法识别令牌......

这是我放[Tree]时得到的IParseTree

"(开始 [测试])"


与数字相同,它确实可以很好地识别孤独的数字,例如112312.5等,但不能识别像1+2这样的表达式。

您是否知道为什么解析器无法识别columnNames规则,但可以很好地与string规则配合使用?

可能是因为"StringChar"的定义不正确?它不处理"]"

也许您想将字符串字符定义为:

fragment
StringChar
:   ~["\]]
|   EscapeSequence
;

如果这是我的语法,我会像带引号的字符串一样定义一个 QuotedStringChar,并将 BracketStringChar 定义为 ~[\]\\] 以用于您的括号列名称。

欢迎来到词法级别的调试语法,并为不同类型的字符串定义不同类型的"引号"。 这是很常见的。(你应该看到Ruby,你可以在字符串的开头定义字符串引号,ick。

我最终通过推杆让它工作:

QuotedStringChars
    :   '"' ~["]+ '"'
    ;
BracketStringChars
    :   '[' ~[]]+ ']'
    ;

在引号或方括号之间取任何字符。然后:

primary
    :   literal #PrimLiteral
    |   number  #PrimNumber
    ;
literal
    :   QuotedStringChars   #OneString
    |   BracketStringChars  #ColumnName
    |   number              #NUMBER
    ;
number
    :   DecimalIntegerLiteral       #DecimalIntegerLiteral
    |   DecimalFloatingPointLiteral #FloatLiteral
    ;

literal规则有助于区分带引号的字符串、括号字符串和数字。

primary规则和literal规则中存在重复的number,因为我需要在应用程序中为每个规则提供不同的行为。

我在Ira Baxter的好建议下做到了这一点:)

希望这能帮助像我这样的其他 ANTLR 新手拥有更好的 了解:)

相关内容

  • 没有找到相关文章

最新更新