c# - 带有手动词法分析器的 ANTLR 解析器

标签 c# antlr lexer parser-generator

我正在将基于 C# 的编程语言编译器从手动词法分析器/解析器迁移到 Antlr。

Antlr 一直让我很头疼,因为它通常大部分都能正常工作,但也有一些小部分不能正常工作,而且解决起来非常痛苦。

我发现我的大部分头痛是由 Antlr 的词法分析器部分引起的,而不是解析器。然后我注意到 parser grammar X; 并意识到也许我可以使用我手动编写的词法分析器,然后使用 Antlr 生成的解析器。

所以我正在寻找有关此主题的更多文档。我想自定义 ITokenStream 可以工作,但似乎几乎没有关于此主题的在线文档...

最佳答案

我发现了方法。这可能不是最好的方法,但它似乎确实有效。

  1. Antlr 解析器接收一个ITokenStream 参数
  2. Antlr 词法分析器本身就是 ITokenSource
  3. ITokenSource 是一个比 ITokenStream
  4. 简单得多的接口(interface)
  5. ITokenSource 转换为 ITokenStream 的最简单方法是使用 CommonSourceStream,它接收 ITokenSource 参数

所以现在我们只需要做两件事:

  1. 将语法调整为仅解析器
  2. 实现 ITokenSource

调整语法非常简单。只需删除所有词法分析器声明并确保将语法声明为 parser grammar。为方便起见,此处发布了一个简单示例:

parser grammar mygrammar;

options
{
    language=CSharp2;
}

@parser::namespace { MyNamespace }

document:   (WORD {Console.WriteLine($WORD.text);} |
        NUMBER {Console.WriteLine($NUMBER.text);})*;

请注意,以下文件将输出 class mygrammar 而不是 class mygrammarParser

所以现在我们要实现一个“假的”词法分析器。 我个人使用了以下伪代码:

TokenQueue q = new TokenQueue();
//Do normal lexer stuff and output to q
CommonTokenStream cts = new CommonTokenStream(q);
mygrammar g = new mygrammar(cts);
g.document();

最后,我们需要定义TokenQueueTokenQueue 不是绝对必要的,但我使用它是为了方便。 它应该有接收词法分析器标记的方法,以及输出 Antlr 标记的方法。因此,如果不使用 Antlr native token ,则必须实现一种转换为 Antlr token 的方法。 此外,TokenQueue 必须实现 ITokenSource

请注意,正确设置 token 变量非常重要。最初,我遇到了一些问题,因为我错误地计算了 CharPositionInLine。如果这些变量设置不正确,那么解析器可能会失败。 此外,正常 channel (未隐藏)为 0。

到目前为止,这似乎对我有用。我希望其他人也觉得它有用。 我愿意接受反馈。特别是,如果您找到更好的方法来解决这个问题,请随时发表单独的回复。

关于c# - 带有手动词法分析器的 ANTLR 解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4414166/

相关文章:

c++ - 标记一个字符串,并将每个分隔符放在它自己的标记中

c# - 在 .NET 正则表达式中使用 "\b"

c# - 将列表格式化为字符串

java - Java 源文件中的新行 : How to test for them using Character class?

ANTLR 日期和整数匹配

javascript - 在 ANTLR4 中使用访问者的正确方法(javascript 目标)

Antlr(词法分析器): matching the right token

从共享驱动器运行的 C# 网络连接

c# - 属性的 getter 和 setter 的 Lambda

使用 ANTLRv4 的 Java DSL 实现