![](/img/trans.png)
[英]Implementing translator using ANTLR by embedding semantic actions as Java code in the g4 grammar file
[英]Using Java code in antlr grammar g4 file
我想定义一个语法来解析与测量单位有关的单词,例如千克:'kg','KG','千克','公斤','l','升','升'等。
我已经在使用Java enum
类来执行类似的操作,以验证应该表示度量单位的输入字符串。
我想知道是否可以在ANTLR语法文件中的enum类中重用已定义的度量单位。 基本上我想在.g4语法文件中设置词法分析器 ,如:
UNITS: UnitMeasures.values()
.values()
方法返回UnitMeasures
枚举Java类中的枚举值,这与ANTLR语法词法分析器“应该是等价的”:
UNITS: ('kg' | 'KG' | 'kilograms' | 'l' | 'litres' | 'liters' );
我试图这样做的原因是:
有可能以某种方式避免这种代码重复吗?
如果您的程序中尚未存在枚举,我建议根据语法本身生成运行时工件。
由于您已经定义了枚举,因此在使用AbstractParseTreeVisitor完成解析后,让我们实现单元识别。
1)添加units
解析器规则并概括你的UNITS
词法分析器规则:
...
unit : ID
;
...
ID: [a-zA-Z_0-9]+ ; // whatever you want/need
...
现在你的语法不会复制任何代码,但你的单位规则太笼统了。 我们将在java方面解决这个问题。
2)生成访问者并覆盖visitUnit(UnitContext)
。
@Override
public Object visitUnit(UnitContext ctx) {
String unitId = ctx.ID();
try{
// Next line will throw exception if unitId is not
// the name of one of your enums.
UnitMeasures unit = UnitMeasures.valueOf(unitId);
// do something maybe?
} catch (IllegalArgumentException(e) {
throw new RuntimeException("Invalid unit: " + unitId);
}
return super.visitUnit(ctx);
}
这将消除任何代码重复。 现在,无论UnitMeasures
向UnitMeasures
添加新的枚举,您都不必改变语法。 您甚至不需要重新生成解析器。
另一个选项:这将为您的语法添加一个java依赖项,但您可以在unit
规则之后添加一些小动作,如果ID
不是基于enum
的有效单元,则可以做出相应的响应。
unit : ID
{
try {
UnitMeasures.valueOf($unit.text);
}
catch(IllegalArgumentException e) {
//report invalid unit
}
}
;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.