gpt4 book ai didi

antlr4 - 在访问 Antlr 规则时区分可选 token

转载 作者:行者123 更新时间:2023-12-01 02:21:40 24 4
gpt4 key购买 nike

这个问题是关于如何在访问 antlr 规则时区分可选 token 。

我在 antlr4 语法中定义了一个名为“assign”的解析器规则,该规则尝试将表达式的结果分配给由 INT 表示的标记,例如 215="FOO"。它还允许分配给标记索引,例如 215[2] = "FOO"。我的问题是如何通过在分配规则评估期间查看 antlr 提供的对象来区分形式 215 与形式 215[2] 的 INT?

assign  : INT '=' expr  ;
INT : '-'? DIGIT+ ('[' DIGIT+ ']')?;
DIGIT : [0-9] ;

我已经定义了一个访问者方法来捕获解析器对 token 流的“分配”规则的评估:

215[2]=“FOO”
@Override
public String visitAssign(@NotNull FixRulesParser.AssignContext ctx) {
String left = ctx.getStart().getText();
String right = ctx.getStop().getText();
...

此时 left = "215[2]"和 right = "FOO"

ctx 对象是否提供了一种方法来确定赋值的左侧 (215[2]) 是否实际包含由 INT 定义的可选“[2]”?我想区分 215[2] 与 215 形式的 INT。我使用 Java 正则表达式来解析“左”(见下文)以做出决定,但我想知道是否可以直接从 antlr 获得答案。
Pattern p = Pattern.compile("(-?\\d+)((\\[)(\\d+)(\\]))?");

最佳答案

我在阅读后找到的一种解决方案 "The Antlr Reference - Chapter 12"是将索引“[2]”定义为它自己的词法分析器标记并将其放在单独的 channel 上。

assign  : INT '=' expr  ;
INT : '-'? DIGIT+ ;
IDX : '[' DIGIT+ ']' -> channel(TAG_INDEX);
DIGIT : [0-9] ;

然后我可以在visitAssign()中做出决定:
@Override
public String visitAssign(@NotNull FixRulesParser.AssignContext ctx) {
BufferedTokenStream tokens = tokenStream; // passed in to the constructor as arg
Token t = tokens.get(1);
int type = t.getType();
if (type == FixRulesParser.IDX) {
System.out.println("YES");
} else {
System.out.println("NO");
}

我认为这里的教训是,如果您需要单独引用 IDX,则不应将其与任何其他 token 结合使用。

仍然让我困惑的一件事是,如果我删除 TAG_INDEX channel :
IDX : '[' DIGIT+ ']';

我得到:第 1:4 行在输入 '215[2]' 处没有可行的替代方案

知道为什么会很好,但至少我有一个解决方案。

关于antlr4 - 在访问 Antlr 规则时区分可选 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20014741/

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