【问题标题】:ANTLR4 dynamic token typeANTLR4 动态令牌类型
【发布时间】:2017-03-12 13:37:35
【问题描述】:

我正在词法分析的语言需要能够根据运行时配置热交换关键字。

只要您可以在语法 (Java) 中嵌入特定于目标的代码,执行此操作相对简单:1

lexer grammar LanguageLexer;

tokens {
If, Else, While // etc
}

@header {
import java.util.Map;
}

@members {
private Map<String, Integer> keywords;
public NafiLexer(CharStream input, Map<String, Integer> keywords) {
    this(input);
    this.keywords = keywords;
}
}

WS: [ \n\t\r]+ -> skip;
ID: [a-zA-Z]+ { if(keywords.containsKey(getText())) setType(keywords.get(getText())); };

但是,我想从我的 .g4 文件中删除所有特定于目标的代码,因为我的 .g4s 将用于不同项目的多种目标语言。

Parser 中,您可以使用Listener 删除嵌入的操作并将语法与特定于应用程序的代码分离。但是,如果在 Lexer 级别2 存在这样做的方法,我还没有找到它(因此提出这个问题)。

实现这一点的方法似乎是包装从Lexer 中提取的TokenStream。此包装 TokenStream 将在提供时读取 Tokens,并将当前在嵌入式操作中的转换应用于存在的任何 ID 标记。

这(理论上)并不难实现;然而,这感觉就像只使用已经定义的 ANTLR 符号就应该可以实现的功能。所以,问题是:是否有可能在现有的 ANTLR 系统中有条件地更改通过 TokenStream 的令牌类型? 如果不能,那么完成该任务的最低摩擦方式是什么?使用 Java 库的示例将是首选,因为这是我最熟悉的。

作为一个子问题:如果我最终为我所需的目标创建了一个TokenTransformationStream,是否值得建议将其添加到现有库中? (我可以为所有当前提供的目标创建符号。)


1 是的,如果您使用常规构造函数构造 Lexer,这将崩溃。在实际应用程序中,可能值得修复它,但对于本示例,这并不重要。

2 我觉得这对于词法分析器级别来说是一项合适的任务,原因有几个。主要原因是总是将关键字作为关键字标记传递似乎很常见,然后,如有必要,允许它们作为解析器级别的标识符(例如上下文相关的关键字)。此外,其他简单地询问如何 来实现此效果的问题建议了一种与上述提供的嵌入式操作解决方案基本等效的方法。

【问题讨论】:

  • 我可以为这个任务找到的最有希望的符号是org.antlr.v4.runtime.TokenStreamRewriter,但如果我正确地阅读了它的 javadoc,它只是用于更改文本表示。
  • 你能在词法分析/解析开始之前以某种方式知道这个runtime configuration吗?
  • @cantSleepNow 是的,它以前是已知的,并且在每个运行时都是不变的。
  • 你能使用词法分析器模式吗?因为与它相结合,您可以在没有特定语言代码的情况下设置类型。
  • @cantSleepNow 我看不出有什么理由我不能,但我也看不出模式在这种情况下会有什么帮助。如果您认为模式可以解决问题,请添加答案

标签: java antlr antlr4


【解决方案1】:

这可能不是问题的答案,但评论太长了。
我指的是 cmets 中的词法分析器模式,因为我专注于这部分 hot-swap keywords。我不知道您为什么需要更改令牌类型,但如果您使用词法分析器模式,您可能不会关心它。

唯一需要注意的是需要一些关键字来指示词法分析器模式的变化。基本上,一种词法分析器模式是子词法分析器语法(排序)。

RUNTIME_CFG_! : 'runtime_cfg_1' -> mode(m_CGF_1);
...
mode m_CGF_1;
KEYWORD1 : 'key1;
...

如果有一些相同的关键字,你也可以使用词法分析函数type* 来显式设置令牌的类型。

*我现在不记得它是如何被调用的,但是通过词法分析器函数,我的意思是像 modeskip 等这样的函数之一。

【讨论】:

    猜你喜欢
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多