Antlr4 left recursive rule 包含一个左递归选择,它后面可以跟一个空字符串
Antlr4 left recursive rule contains a left recursive alternative which can be followed by the empty string
所以我定义了一个语法来解析一个C风格的语法语言:
grammar mygrammar;
program
: (declaration)*
(statement)*
EOF
;
declaration
: INT ID '=' expression ';'
;
assignment
: ID '=' expression ';'
;
expression
: expression (op=('*'|'/') expression)*
| expression (op=('+'|'-') expression)*
| relation
| INT
| ID
| '(' expression ')'
;
relation
: expression (op=('<'|'>') expression)*
;
statement
: expression ';'
| ifstatement
| loopstatement
| printstatement
| assignment
;
ifstatement
: IF '(' expression ')' (statement)* FI ';'
;
loopstatement
: LOOP '(' expression ')' (statement)* POOL ';'
;
printstatement
: PRINT '(' expression ')' ';'
;
IF : 'if';
FI : 'fi';
LOOP : 'loop';
POOL : 'pool';
INT : 'int';
PRINT : 'print';
ID : [a-zA-Z][a-zA-Z0-9]*;
INTEGER : [0-9]+;
WS : [ \r\n\t] -> skip;
我可以这样解析一个简单的测试:
int i = (2+3)*3/2*(3+36);
int j = i;
int k = 2*1+i*3;
if (k > 2)
k = k + 1;
i = i / 3;
j = j / 3;
fi;
loop (i < 10)
i = i + 1 * (i+k);
j = (j + 1) * (j-k);
k = i + j;
print(k);
pool;
但是,当我想在 intelliJ 中生成 ANTLR Recogonizers 时,出现了这个错误:
sCalc.g4:19:0: left recursive rule expression contains a left recursive alternative which can be followed by the empty string
请问这是不是我的ID
可能是一个空字符串造成的?
这与您的 expression
和 relation
规则有关。表达式规则可以在一个 alt 中匹配 relation
,这又递归回 expression.
规则 relation
另外可能不匹配任何内容,因为 (op=('<'|'>') expression)*
更好的方法可能是让 relation
调用 expression
并从 expression
中删除 relation
alt。然后在你现在使用 expression
的任何地方使用 relation
。这是表达式中的典型场景,从低优先级操作作为顶级规则开始,向下钻取到更高优先级规则,最终以简单的表达式规则(或类似规则)结束。
你的语法有几个问题:
- 你在
expression
中有 INT
作为替代,而你可能想要 INTEGER
而不是
- 没有必要做
expression (op=('+'|'-') expression)*
:这样就可以了:expression op=('+'|'-') expression
- ANTLR4 不支持间接左递归规则:您必须在
expression
中包含 relation
应该这样做:
grammar mygrammar;
program
: (declaration)*
(statement)*
EOF
;
declaration
: INT ID '=' expression ';'
;
assignment
: ID '=' expression ';'
;
expression
: expression op=('*'|'/') expression
| expression op=('+'|'-') expression
| expression op=('<'|'>') expression
| INTEGER
| ID
| '(' expression ')'
;
statement
: expression ';'
| ifstatement
| loopstatement
| printstatement
| assignment
;
ifstatement
: IF '(' expression ')' (statement)* FI ';'
;
loopstatement
: LOOP '(' expression ')' (statement)* POOL ';'
;
printstatement
: PRINT '(' expression ')' ';'
;
IF : 'if';
FI : 'fi';
LOOP : 'loop';
POOL : 'pool';
INT : 'int';
PRINT : 'print';
ID : [a-zA-Z][a-zA-Z0-9]*;
INTEGER : [0-9]+;
WS : [ \r\n\t] -> skip;
也不是说这个(statement)*
可以简单写成statement*
所以我定义了一个语法来解析一个C风格的语法语言:
grammar mygrammar;
program
: (declaration)*
(statement)*
EOF
;
declaration
: INT ID '=' expression ';'
;
assignment
: ID '=' expression ';'
;
expression
: expression (op=('*'|'/') expression)*
| expression (op=('+'|'-') expression)*
| relation
| INT
| ID
| '(' expression ')'
;
relation
: expression (op=('<'|'>') expression)*
;
statement
: expression ';'
| ifstatement
| loopstatement
| printstatement
| assignment
;
ifstatement
: IF '(' expression ')' (statement)* FI ';'
;
loopstatement
: LOOP '(' expression ')' (statement)* POOL ';'
;
printstatement
: PRINT '(' expression ')' ';'
;
IF : 'if';
FI : 'fi';
LOOP : 'loop';
POOL : 'pool';
INT : 'int';
PRINT : 'print';
ID : [a-zA-Z][a-zA-Z0-9]*;
INTEGER : [0-9]+;
WS : [ \r\n\t] -> skip;
我可以这样解析一个简单的测试:
int i = (2+3)*3/2*(3+36);
int j = i;
int k = 2*1+i*3;
if (k > 2)
k = k + 1;
i = i / 3;
j = j / 3;
fi;
loop (i < 10)
i = i + 1 * (i+k);
j = (j + 1) * (j-k);
k = i + j;
print(k);
pool;
但是,当我想在 intelliJ 中生成 ANTLR Recogonizers 时,出现了这个错误:
sCalc.g4:19:0: left recursive rule expression contains a left recursive alternative which can be followed by the empty string
请问这是不是我的ID
可能是一个空字符串造成的?
这与您的 expression
和 relation
规则有关。表达式规则可以在一个 alt 中匹配 relation
,这又递归回 expression.
规则 relation
另外可能不匹配任何内容,因为 (op=('<'|'>') expression)*
更好的方法可能是让 relation
调用 expression
并从 expression
中删除 relation
alt。然后在你现在使用 expression
的任何地方使用 relation
。这是表达式中的典型场景,从低优先级操作作为顶级规则开始,向下钻取到更高优先级规则,最终以简单的表达式规则(或类似规则)结束。
你的语法有几个问题:
- 你在
expression
中有INT
作为替代,而你可能想要INTEGER
而不是 - 没有必要做
expression (op=('+'|'-') expression)*
:这样就可以了:expression op=('+'|'-') expression
- ANTLR4 不支持间接左递归规则:您必须在
expression
中包含
relation
应该这样做:
grammar mygrammar;
program
: (declaration)*
(statement)*
EOF
;
declaration
: INT ID '=' expression ';'
;
assignment
: ID '=' expression ';'
;
expression
: expression op=('*'|'/') expression
| expression op=('+'|'-') expression
| expression op=('<'|'>') expression
| INTEGER
| ID
| '(' expression ')'
;
statement
: expression ';'
| ifstatement
| loopstatement
| printstatement
| assignment
;
ifstatement
: IF '(' expression ')' (statement)* FI ';'
;
loopstatement
: LOOP '(' expression ')' (statement)* POOL ';'
;
printstatement
: PRINT '(' expression ')' ';'
;
IF : 'if';
FI : 'fi';
LOOP : 'loop';
POOL : 'pool';
INT : 'int';
PRINT : 'print';
ID : [a-zA-Z][a-zA-Z0-9]*;
INTEGER : [0-9]+;
WS : [ \r\n\t] -> skip;
也不是说这个(statement)*
可以简单写成statement*