parsing - 打破头脑如何使用规则获取令牌的位置 - ANTLR4 / 语法
问题描述
我正在使用 ANLTR 编写一个小语法,并且我有这样的规则:
operation : OPERATION (IDENT | EXPR) ',' (IDENT | EXPR);
...
OPERATION : 'ADD' | 'SUB' | 'MUL' | 'DIV' ;
IDENT : [a-z]+;
EXPR : INTEGER | FLOAT;
INTEGER : [0-9]+ | '-'[0-9]+
FLOAT : [0-9]+'.'[0-9]+ | '-'[0-9]+'.'[0-9]+
现在在 Java 内部的侦听器中,在操作由 IDENT 和 EXPR 组成的这种情况下,我如何确定它们出现的顺序?显然,规则可以同时匹配
ADD 10, d
或
匹配,ADD d, 10
但在由 ANTLR4 生成的规则的侦听器中,是否同时存在IDENT()
以及EXPR()
如何获取它们的顺序,因为我想正确分配左右操作数。
一直在为此头疼,有没有简单的方法或者我应该重写规则本身?这ctx.getTokens ()
要求我给出令牌类型,这违背了目的,因为如果我指定它们的类型,我无法获得规则中令牌的序列。
解决方案
你可以这样做:
operation : OPERATION lhs=(IDENT | EXPR) ',' rhs=(IDENT | EXPR);
然后在你的听众里面,这样做:
@Override
public void enterOperation(TParser.OperationContext ctx) {
if (ctx.lhs.getType() == TParser.IDENT) {
// left hand side is an identifier
} else {
// left hand side is an expression
}
// check `rhs` the same way
}
从哪里来TParser
的语法文件T.g4
。相应地改变它。
另一种解决方案是这样的:
operation
: OPERATION ident_or_expr ',' ident_or_expr
;
ident_or_expr
: IDENT
| EXPR
;
然后在你的听众中:
@Override
public void enterOperation(TParser.OperationContext ctx) {
Double lhs = findValueFor(ctx.ident_or_expr().get(0));
Double rhs = findValueFor(ctx.ident_or_expr().get(1));
...
}
private Double findValueFor(TParser.Ident_or_exprContext ctx) {
if (ctx.IDENT() != null) {
// it's an identifier
} else {
// it's an expression
}
}
推荐阅读
- c# - 等到单击事件在 foreach 循环中继续
- javascript - React - 更新图状态 Onclick 重新渲染问题
- javascript - Javascript - 在地图函数内的数组中间添加项目
- javascript - 如何创建映射到嵌入式 JSON 数据模型的 HTML 输入表单?
- sql - 计算不同的记录但排除当前列值
- c# - Postgres 从字符串列表中选择
- javascript - Vite 是否也适用于页面内备用 javascript 'widgets' 或组件?
- kotlin - 如何禁用 onSwiped 和 onChildDraw (ItemTouchHelper) Kotlin
- html - Angular:ngIf 无法识别枚举类型
- r - 使用循环为箱线图的列名设置正确的 Y 轴标签