ANTLR Parser带有手动词法分析器

时间:2010-12-10 23:21:20

标签: c# antlr lexer parser-generator

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

Antlr一直给我带来严重的麻烦,因为它通常主要有效,但是有些小部分没有,并且难以解决。

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

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

1 个答案:

答案 0 :(得分:7)

我发现了怎么样。它可能不是最好的方法,但它似乎肯定有效。

  1. Antlr解析器会收到ITokenStream参数
  2. Antlr lexers本身就是ITokenSource s
  3. ITokenSource是比ITokenStream
  4. 更简单的界面
  5. ITokenSource转换为ITokenStream的最简单方法是使用CommonSourceStream,其中会收到ITokenSource参数
  6. 所以现在我们只需做两件事:

    1. 将语法调整为仅解析器
    2. 实施ITokenSource
    3. 调整语法非常简单。只需删除所有词法分析器声明,并确保将语法声明为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本机令牌,则必须实现convert-to-Antlr-token方法。 此外,TokenQueue必须实施ITokenSource

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

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