Antlr4左递归规则包含一个左递归替代项,后面可以跟一个空字符串
所以我定义了一个语法来解析C风格的语法语言:Antlr4左递归规则包含一个左递归替代项,后面可以跟一个空字符串,antlr4,left-recursion,Antlr4,Left Recursion,所以我定义了一个语法来解析C风格的语法语言: grammar mygrammar; program : (declaration)* (statement)* EOF ; declaration : INT ID '=' expression ';' ; assignment : ID '=' expression ';' ; expression : expression (op=('*'|'/') expression)* | expression (op=('+'|'-')
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;
语法我的语法;
程序
:(声明)*
(声明)*
EOF
;
宣言
:INT ID'='表达式';'
;
分配
:ID'='表达式';'
;
表达
:表达式(op=(“*”|“/”)表达式)*
|表达式(op=(“+”|“-”)表达式)*
|关系
|INT
|身份证
|“(“表达式”)”
;
关系
:表达式(op=(“”)表达式)*
;
陈述
:表达式“;”
|国际单项体育联合会声明
|循环语句
|打印语句
|分配
;
国际单项体育联合会声明
:如果“(“表达式”)”(语句)*FI“;”
;
循环语句
:循环“(“表达式”)”(语句)*池“;”
;
打印语句
:打印“(“表达式”)”;'
;
如果:‘如果’;
FI:‘FI’;
循环:‘循环’;
游泳池:“游泳池”;
INT:‘INT’;
打印:“打印”;
ID:[a-zA-Z][a-zA-Z0-9]*;
整数:[0-9]+;
WS:[\r\n\t]->跳过;
我可以这样分析一个简单的测试:
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;
inti=(2+3)*3/2*(3+36);
int j=i;
int k=2*1+i*3;
如果(k>2)
k=k+1;
i=i/3;
j=j/3;
fi;
环路(i<10)
i=i+1*(i+k);
j=(j+1)*(j-k);
k=i+j;
印刷品(k);
水塘
但是,当我想在intelliJ中生成ANTLR重定位程序时,我遇到了以下错误:
sCalc.g4:19:0:左递归规则表达式包含一个左递归替代项,该替代项后面可以跟空字符串
我想知道这是否是由我的
ID
可能是空字符串引起的?这是关于你的表达式和关系的规则。表达式规则可以在一个alt中匹配关系
,而该alt又返回到表达式。
规则关系
由于(op=('')表达式)*
更好的方法可能是使用关系
调用表达式
并从表达式
中删除关系
alt。然后使用关系
现在使用表达式
的所有地方。这是表达式中的典型场景,从低优先级操作开始作为顶级规则,向下钻取到更高优先级的规则,最终以简单的表达式规则(或类似规则)结束。您的语法有几个问题:
- 在
expression
中有INT
作为替代,而您可能需要INTEGER
- 无需执行
表达式(op=(“+”|“-”)表达式)*
:这将执行:表达式op=(“+”|“-”)表达式
- ANTLR4不支持间接左递归规则:必须在
表达式中包含关系
像这样的事情应该可以做到:
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;
语法我的语法;
程序
:(声明)*
(声明)*
EOF
;
宣言
:INT ID'='表达式';'
;
分配
:ID'='表达式';'
;
表达
:表达式op=(“*”|“/”)表达式
|表达式op=(“+”|“-”)表达式
|表达式op=(“”)表达式
|整数
|身份证
|“(“表达式”)”
;
陈述
:表达式“;”
|国际单项体育联合会声明
|循环语句
|打印语句
|分配
;
国际单项体育联合会声明
:如果“(“表达式”)”(语句)*FI“;”
;
循环语句
:循环“(“表达式”)”(语句)*池“;”
;
打印语句
:打印“(“表达式”)”;'
;
如果:‘如果’;
FI:‘FI’;
循环:‘循环’;
游泳池:“游泳池”;
INT:‘INT’;
打印:“打印”;
ID:[a-zA-Z][a-zA-Z0-9]*;
整数:[0-9]+;
WS:[\r\n\t]->跳过;
也不是说这个(语句)*
可以简单地写成语句*
谢谢,这很有效。但我也想知道,antlr4如何简单地将0与多个语句匹配,而不使用“()”
捕获一组语句。呃,我不明白(a)*
与a*
完全相同。如果你有不止一件事情要重复,那么你需要在它们周围加上括号:(ab)*
(与ab*
不同)