我在ANTLR中为类似Java的if语句编写了一个语法,如下所示:
if_statement
: 'if' expression
(statement | '{' statement+ '}')
('elif' expression (statement | '{' statement+ '}'))*
('else' (statement | '{' statement+ '}'))?
;
我已经实施了#34;声明"和"表达"正确,但if_statement给了我以下错误:
Decision can match input such as "'elif'" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
|---> ('elif' expression (statement | '{' statement+ '}'))*
warning(200): /OptDB/src/OptDB/XL.g:38:9:
Decision can match input such as "'else'" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
|---> ('else' (statement | '{' statement+ '}'))?
好像" elif"和"否则"块。 基本上,我们可以有0或更多" elif"块,所以我用*包裹它们 我们也可以有0或1"否则"块,所以我用它包裹它。?
什么似乎导致错误?
=============================================== =========================
我还将"表达式"的实现放在一起。和#34;陈述":
statement
: assignment_statement
| if_statement
| while_statement
| for_statement
| function_call_statement
;
term
: IDENTIFIER
| '(' expression ')'
| INTEGER
| STRING_LITERAL
| CHAR_LITERAL
| IDENTIFIER '(' actualParameters ')'
;
negation
: 'not'* term
;
unary
: ('+' | '-')* negation
;
mult
: unary (('*' | '/' | 'mod') unary)*
;
add
: mult (('+' | '-') mult)*
;
relation
: add (('=' | '/=' | '<' | '<=' | '>=' | '>') add)*
;
expression
: relation (('and' | 'or') relation)*
;
actualParameters
: expression (',' expression)*
;
答案 0 :(得分:1)
因为你的语法允许语句块而不是按{...}
分组,所以你自己有一个经典的dangling else歧义。
简短说明。输入:
if expr1 if expr2 ... else ...
可以解析为:
if expr1
if expr2
...
else
...
但也是这样:
if expr1
if expr2
...
else
...
要消除歧义,可以改变:
(statement | '{' statement+ '}')
成:
'{' statement+ '}'
// or
'{' statement* '}'
通过查看if
else
所属的大括号,或添加a predicate以强制解析器选择解析1 ,这一点很清楚:
if_statement
: 'if' expression statement_block
(('elif')=> 'elif' expression statement_block)*
(('else')=> 'else' statement_block)?
;
statement_block
: '{' statement* '}'
| statement
;