antlr4 - 如何解决“以下规则集相互左递归”ANTLR错误
问题描述
以下几组规则是相互左递归的 [valeurBooleene, valeur]
我知道 ANTLR 可以很好地处理左递归规则,但只能在一个规则中,而不是在规则之间。
我必须重写我的规则来解决相互左递归的问题,但我不知道如何......
grammar minimal;
constante:
bool = BOOLEAN
| intgr = INTEGER
;
valeurBooleene:
'(' val = valeurBooleene ')'
| bool = BOOLEAN
| 'non' not = valeur
| leftValue = valeur '=' rightValue = valeur
;
valeur:
'(' val = valeur ')'
| cst = constante
| booleanValue = valeurBooleene
| '|' absolute = valeur '|'
| '-' opposite = valeur
;
condition:
'(' cond = condition ')'
| bool = valeurBooleene
;
si:
'Si' cond = condition 'alors' ( thenActions += action )+
( 'sinon' ( elseActions += action )+ )?
;
system:
( actions += action )+
EOF
;
action:
ifClause = si
;
BOOLEAN:
'false'
| 'true'
| 'faux'
| 'vrai'
;
INTEGER:
[0-9]+
;
WS:
[ \n\t\r]+ -> skip
;
解决方案
最后,我遵循sepp2k提供的建议,如下所示:
grammar minimal;
value:
'(' val = value ')' # Parenthesis
| b = BOOLEAN # Boolean
| 'non' not = value # Boolean
| l = value '=' r = value # Boolean
| i = INTEGER # Numeric
| '|' abs = value '|' # Numeric
| '-' opposite = value # Numeric
;
condition:
'(' condition ')'
| cond = value
;
ifStmnt:
'IF' condition 'THEN' ( actionsThen += action )+
( 'ELSE' ( actionsElse += action )+ )?
;
system:
( actions += action )+
EOF
;
print:
'print' val = value
;
action:
ifs = ifStmnt
| pr = print
;
BOOLEAN:
'false'
| 'true'
;
INTEGER:
[0-9]+
;
WS:
[ \n\t\r]+ -> skip
;
标签创建扩展 ValueContext 的类,我像这样使用它们:
package com.thalesgroup.dms.stimulus.factories;
import minimal.minimalParser.BooleanContext;
import minimal.minimalParser.ConditionContext;
import minimal.minimalParser.NumericContext;
import minimal.minimalParser.ParenthesisContext;
import minimal.minimalParser.ValueContext;
public class Sample {
void analyze( ValueContext ctxt ) {
if( ctxt instanceof ParenthesisContext ) {
analyze(((ParenthesisContext)ctxt).val );
}
else if( ctxt instanceof BooleanContext ) {
final BooleanContext bc = (BooleanContext)ctxt;
analyze( bc );
}
else if( ctxt instanceof NumericContext ) {
final NumericContext nc = (NumericContext)ctxt;
analyze( nc );
}
}
void analyze( ConditionContext ctxt ) {
if( ctxt.cond instanceof BooleanContext ) {
final BooleanContext boolCtxt = (BooleanContext)ctxt.cond;
// build a condition from a BooleanContext
analyze( boolCtxt );
}
else {
throw new IllegalStateException();
}
}
void analyze( BooleanContext ctxt ) {
if( ctxt.b != null ) {
final String literal = ctxt.b.getText();
if( literal.equals( "true" )) {
// deal with a boolean literal 'true'
}
else if( literal.equals( "false" )) {
// deal with a boolean literal 'false'
}
}
else if( ctxt.not != null ) {
final BooleanContext bCtxt = (BooleanContext)ctxt.not;
// deal with a 'not' operation
}
else if( ctxt.l != null ) {
final ValueContext left = ctxt.l;
final ValueContext right = ctxt.r;
// deal with 'equals'
}
else {
// ???
}
}
void analyze( NumericContext ctxt ) {
if( ctxt.abs != null ) {
// deal with abs( x )
}
else if( ctxt.opposite != null ) {
// deal with - x
}
else if( ctxt.i != null ) {
// deal with literal integer
}
}
}
推荐阅读
- testing - 将自定义会话数据添加到 clojure 中的 jsoup POST 请求
- windows - SSL 上的窗口服务
- excel - 将网页数据导入 Excel
- c++ - 如何在循环中初始化 QList 中的对象
- sql-server - 从 SSIS 脚本任务传递文件名
- matplotlib - 通过 Anaconda 安装的 Windows 中 Cartopy 的存储库在哪里?
- java - Spring Boot tomcat-embed-core-9.0.21.jar:zip 文件为空
- sql - 如何在 SQL Server 中的 DATETIME 列上查询 DATE?
- fiware - 从 FIWARE ORION 中的 OpenWeatherMap 检索预报数据
- python - TypeError: TimestampType 不能接受对象
和