我尝试使用ANTLR制作具有以下细节的语法。
它可以解析如下标识符:
foo > bar > 67
其中foo> bar是标识符,因为如果>后跟一个包含在标识符中的字母,其后是一个大于运算符的字母。
我应该解析像
这样的东西((a = 1) AND (b = 2)) OR (c = 3)
其中()是必要的。
我对这个主题和ANTLR真的很陌生,希望有人可以提供帮助。
我现在有这个语法
grammar testgrammer;
start : statement EOF;
statement
: operation (AND operation)*;
operation
: '(' ID OPERATOR INT ')';
AND : 'AND';
OPERATOR: '=' | '>';
ID
: ('a'..'z'| 'A'..'Z')+ (WS '>' WS ('a'..'z' | 'A'..'Z')+)?
;
WS
: ' '+ {skip();}
;
INT : '0'..'9'+
;
但我无法弄清楚如何在>之间切换。在id和>作为运营商。
答案 0 :(得分:1)
首先,让我们感到困惑:"foo > bar"
是标识符,"foo > 67"
是表达式。
由于你允许在这样的标识符中包含空格,你的词法分析器会跳过"foo > 67"
之类的输入,因为在"foo > "
之后,它会尝试使用一个字母,但会看到一个数字。词法分析器不会从"foo > "
回溯,因为没有可以从中创建单个标记(请注意,词法分析器永远不会放弃它消耗的字符!)。
为了解决这个问题,你必须确保词法分析器匹配" > "
后跟一些字母。你可以使用句法谓词(( ... )=>
部分):
Id
: IdPart ((Spaces? '>' Spaces? IdPart)=> Spaces? '>' Spaces? IdPart)*
;
SpaceChars
: (Spaces | '\r' | '\n') {skip();}
;
fragment Digit : '0'..'9';
fragment Letter : 'a'..'z' | 'A'..'Z';
fragment Spaces : (' ' | '\t')+;
fragment IdPart : Letter (Letter | Digit)*;
请注意,您无法在SpaceChars
内使用规则Id
,因为该规则会调用skip()
方法。