带括号表达式的 ANTLR 语法问题
我正在使用 ANTLRWorks 1.4.2 创建一个简单的语法,以便将用户提供的表达式评估为布尔结果。这最终将成为更大语法的一部分,但我对当前的片段有一些疑问。我希望用户能够使用以下表达式:
2 > 1
2 > 1和3< 1
(2 > 1 或 1 < 3) 且 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';
I'm using ANTLRWorks 1.4.2 to create a simple grammar for the purpose of evaluating an user-provided expression as boolean result. This ultimately will be part of a larger grammar, but I have some questions about this current fragment. I want users to be able to use expressions such as:
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))
The first two expressions are legal in my grammar, but the last two are not, and I am not sure why. Also, ANTLRworks seems to suggest that input such as ((((1 > 2)
with mismatched parentheses is legal, and I am not sure why. So, I seem to be missing out on some insight into the right way to handle parenthetical grouping in a grammar.
How can I change my grammar to properly handle parentheses?
My grammar is below:
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';
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该从以下位置删除
EOF
标记:您通常只在语法入口点之后使用
EOF
(在您的情况下为boolean
)。请注意boolean
是 Java 中的保留字,因此不能用作解析器规则!因此,前两条规则应该如下所示:
您可能还想通过添加以下词法分析器规则来忽略文字空格:(
当然,您可以包含制表符和换行符)
现在所有示例输入都正确匹配(使用 ANTLRWorks 1.4 进行测试) .2 也是如此)。
不,ANTLRWorks 确实如此产生错误,也许不是很明显的错误。 ANTLRWorks 生成的解析树有一个
NoViableAltException
作为叶子,并且“Console”选项卡上有一些错误。You should remove the
EOF
token from:You normally only use the
EOF
after the entry point of your grammar (boolean
in your case). Be carefulboolean
is a reserved word in Java and can therefor not be used as a parser rule!So the first two rules should look like:
And you may also want to ignore literal spaces by adding the following lexer rule:
(you can include tabs an line breaks, of course)
Now all of your example input matches properly (tested with ANTLRWorks 1.4.2 as well).
No, ANTLRWorks does produce errors, perhaps not very noticeable ones. The parse tree ANTLRWorks produces has a
NoViableAltException
as a leaf, and there are some errors on the "Console" tab.