我正在将一个基于C#的编程语言编译器从手动词法分析器/语法分析器迁移到Antlr。
Antlr通常能够大多数地工作,但是总会有一些小部分不能正常运行,让我头疼不已。
我发现Antlr词法分析器部分引起了大部分问题,而不是语法分析器。然后我注意到parser grammar X;
,意识到我可以拥有自己手写的词法分析器和Antlr生成的语法分析器。
因此,我正在寻找更多关于这个主题的文档。我想自定义ITokenStream可能有效,但是似乎几乎没有在线文档涉及这个主题...
我正在将一个基于C#的编程语言编译器从手动词法分析器/语法分析器迁移到Antlr。
Antlr通常能够大多数地工作,但是总会有一些小部分不能正常运行,让我头疼不已。
我发现Antlr词法分析器部分引起了大部分问题,而不是语法分析器。然后我注意到parser grammar X;
,意识到我可以拥有自己手写的词法分析器和Antlr生成的语法分析器。
因此,我正在寻找更多关于这个主题的文档。我想自定义ITokenStream可能有效,但是似乎几乎没有在线文档涉及这个主题...
我找到了方法。这可能不是最好的方法,但它似乎确实有效。
ITokenStream
参数ITokenSource
ITokenSource
比ITokenStream
接口简单得多ITokenSource
转换为ITokenStream
的最简单方法是使用CommonSourceStream
,它接收一个ITokenSource
参数所以现在我们只需要做两件事:
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();
TokenQueue
。虽然TokenQueue
不是必需的,但我为了方便使用它。它应该有接收词法分析器标记的方法,并且有输出Antlr标记的方法。因此,如果不使用Antlr本机标记,则必须实现将其转换为Antlr标记的方法。同时,TokenQueue
必须实现ITokenSource
。CharPositionInLine
而遇到了一些问题。如果这些变量设置不正确,那么解析器可能会失败。
另外,普通通道(非隐藏)为0。