我正在使用ANTLRWorks 1.4.2创建一个简单的语法,以便将用户提供的表达式评估为布尔结果。这最终将成为更大语法的一部分,但我对这个当前片段有一些疑问。我希望用户能够使用以下表达式:
2 > 1
2 > 1 and 3 < 1
(2 > 1 or 1 < 3) and 4 > 1
(2 > 1 or 1 < 3) and (4 > 1 or (2 < 1 and 3 > 1))
前两个表达式在我的语法中是合法的,但最后两个不是,我不知道为什么。此外,ANTLRworks似乎表明((((1 > 2)
等括号不匹配的输入是合法的,我不知道为什么。所以,我似乎错过了对在语法中处理括号分组的正确方法的一些见解。
如何更改语法以正确处理括号?
我的语法如下:
grammar conditional_test;
boolean
: boolean_value_expression
EOF
;
boolean_value_expression
: boolean_term (OR boolean_term)*
EOF
;
boolean_term
: boolean_factor (AND boolean_factor)*
;
boolean_factor
: (NOT)? boolean_test
;
boolean_test
: predicate
;
predicate
: expression relational_operator expression
| LPAREN boolean_value_expression RPAREN
;
relational_operator
: EQ
| LT
| GT
;
expression
: NUMBER
;
LPAREN : '(';
RPAREN : ')';
NUMBER : '0'..'9'+;
EQ : '=';
GT : '>';
LT : '<';
AND : 'and';
OR : 'or' ;
NOT : 'not';
答案 0 :(得分:4)
Chris Farmer写道:
前两个表达式在我的语法中是合法的,但最后两个不是,我不知道为什么。 ...
您应该从以下网址中删除EOF
令牌:
boolean_value_expression
: boolean_term (OR boolean_term)*
EOF
;
您通常只在语法的入口点之后使用EOF
(在您的情况下为boolean
)。注意boolean
是Java中的保留字,因此不能用作解析器规则!
所以前两个规则应该是这样的:
bool
: boolean_value_expression
EOF
;
boolean_value_expression
: boolean_term (OR boolean_term)*
;
您可能还想通过添加以下词法分析器规则来忽略文字空间:
SPACE : ' ' {$channel=HIDDEN;};
(当然,你可以在标签中加入换行符)
现在所有示例输入都匹配正确(也可以使用ANTLRWorks 1.4.2进行测试)。
Chris Farmer写道:
此外,ANTLRworks似乎建议诸如(((1> 2)括号不匹配的输入是合法的,......
不,ANTLRWorks 会产生错误,可能不是很明显。 ANTLRWorks产生的解析树有一个NoViableAltException
作为叶子,“控制台”选项卡上有一些错误。