Parsing ANTLR中的上下文无关语法为if语句抛出错误
我用ANTLR为类似Java的if语句编写了语法,如下所示:Parsing ANTLR中的上下文无关语法为if语句抛出错误,parsing,programming-languages,antlr,grammar,lexical-analysis,Parsing,Programming Languages,Antlr,Grammar,Lexical Analysis,我用ANTLR为类似Java的if语句编写了语法,如下所示: if_statement : 'if' expression (statement | '{' statement+ '}') ('elif' expression (statement | '{' statement+ '}'))* ('else' (statement | '{' statement+ '}'))? ; 我已经正确地实现了“语句”和“表达式”,但
if_statement
: 'if' expression
(statement | '{' statement+ '}')
('elif' expression (statement | '{' statement+ '}'))*
('else' (statement | '{' statement+ '}'))?
;
我已经正确地实现了“语句”和“表达式”,但是if_语句给了我以下错误:
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”和“else”块似乎有问题。
基本上,我们可以有0个或更多的“elif”块,所以我用*
我们也可以有0或1个“else”块,所以我用?来包装它
是什么导致了这个错误
======================================================================== 我还将介绍“表达式”和“语句”的实现:
语句
:赋值语句
|if_语句
|while_语句
|FORU声明
|函数调用语句
;
学期
:标识符
|“(“表达式”)”
|整数
|字符串文字
|字符文字
|标识符“(“actualParameters”)”
;
否定
:“不是”*术语
;
一元
:(“+”|“-”)*否定
;
骡子
:一元((“*”|“/”|“mod”)一元)*
;
添加
:mult((“+”|“-”)mult)*
;
关系
:添加((“=”|“/=”|“)添加)*
;
表达
:关系((‘and’|‘or’)关系)*
;
实际参数
:表达式(“,”表达式)*
;
因为您的语法允许语句块,而不必按{…}
分组,所以您有一个典型的歧义
简短的解释。输入:
if expr1 if expr2 ... else ...
可以解析为:
解析1
但也同样如此:
解析2
要消除歧义,请更改:
(statement | '{' statement+ '}')
进入:
通过查看if
else所属的大括号,或添加以强制解析器选择Parse 1,可以清楚地看到:
if_statement
: 'if' expression statement_block
(('elif')=> 'elif' expression statement_block)*
(('else')=> 'else' statement_block)?
;
statement_block
: '{' statement* '}'
| statement
;
+1:经典问题,经典解决方案,优秀答案,包括规范参考。我希望我能添加一些东西。第三种解决方案是使用Java语言规范中的
NoShortIf
规则,如图所示(搜索以NoShortIf
结尾的规则)。
if expr1
if expr2
...
else
...
(statement | '{' statement+ '}')
'{' statement+ '}'
// or
'{' statement* '}'
if_statement
: 'if' expression statement_block
(('elif')=> 'elif' expression statement_block)*
(('else')=> 'else' statement_block)?
;
statement_block
: '{' statement* '}'
| statement
;