gpt4 book ai didi

java - 在antlr语法g4文件中使用Java代码

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:24:02 29 4
gpt4 key购买 nike

我想定义一个语法来解析与度量单位相关的单词,例如对于千克:'kg'、'KG'、'千克'、'千克'、'l'、'升'、'升'等。

我已经在做类似的事情,使用 Java enum 类来验证应该表示度量单位的输入字符串。

我想知道是否可以在 ANTLR 语法文件中的枚举类中重用已经定义的度量单位。基本上我想在 .g4 语法文件中设置一个 lexer ,例如:

UNITS: UnitMeasures.values()

.values() 方法返回 UnitMeasures 枚举 Java 类中的枚举值,这“应该等同于”ANTLR 语法分析器:

UNITS: ('kg' | 'KG' | 'kilograms' | 'l' | 'litres' | 'liters' );

我尝试这样做的原因是:

  • 我想避免枚举 Java 类和 ANTLR 语法文件之间的代码重复
  • 我不能只使用 ANTLR 并删除枚举 Java 类,因为它已经在许多不同的地方使用;
  • 现在我正尝试在更复杂的场景中使用度量单位,我需要解析数量、度量单位和其他相关内容,因此我决定使用 ANTLR。

是否有可能以某种方式避免这种代码重复?

最佳答案

如果枚举尚未出现在您的程序中,我会建议根据语法本身生成运行时工件。

既然你已经定义了枚举,让我们在解析完成后用 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 添加新的枚举,都无需更改语法。您甚至不需要重新生成解析器。

另一种选择:这将为您的语法添加一个 java 依赖项,但您可以在 unit 规则之后添加一些操作,如果 ID 不是基于以下内容的有效单元,它可以适本地响应你的枚举

unit : ID 
{
try {
UnitMeasures.valueOf($unit.text);
}
catch(IllegalArgumentException e) {
//report invalid unit
}
}
;

关于java - 在antlr语法g4文件中使用Java代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24658582/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com