我是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"
。
当我将IParseTree
放入输入时,我就会在"Test"
中获得以下内容:
“(start(statement(expression(primary(literal(string \”Test \“))))))”
但是当我把[Test]
(与"Test"
几乎相同但用括号而不是引号)时,解析器无法识别令牌......
以下是IParseTree
时我得到的[Tree]
:
“(开始[测试])”
与数字相同,它很好地识别孤独的数字,例如1
,123
,12.5
等,而不是像1+2
...
您是否知道为什么解析器无法识别columnNames
规则但与string
规则配合良好?
答案 0 :(得分:1)
可能是因为“StringChar”的定义不正确?它不处理“]”
也许您想将StringChar定义为:
fragment
StringChar
: ~["\\\]]
| EscapeSequence
;
如果是我的语法,我会为引用的字符串定义一个QuotedStringChar,并将BracketStringChar定义为〜[\] \\] 以用于括号列名。
欢迎在词汇级别调试语法,并为不同类型的字符串定义不同类型的“引号”。这很常见。 (您应该看到Ruby,您可以在字符串的开头定义字符串引用,ick。)。
答案 1 :(得分:0)
我最终通过以下方式让它发挥作用:
QuotedStringChars
: '"' ~[\"]+ '"'
;
BracketStringChars
: '[' ~[\]]+ ']'
;
在引号或括号之间取任何字符。然后:
primary
: literal #PrimLiteral
| number #PrimNumber
;
literal
: QuotedStringChars #OneString
| BracketStringChars #ColumnName
| number #NUMBER
;
number
: DecimalIntegerLiteral #DecimalIntegerLiteral
| DecimalFloatingPointLiteral #FloatLiteral
;
literal
规则有助于区分带引号的字符串,括号字符串和数字。
number
和primary
规则中存在literal
重复项,因为我的应用程序中每个规则都需要不同的行为。
我用Ira Baxter的好建议来管理这个:)
希望这会帮助像我这样的ANTLR其他新手有更好的表现 理解:))