lui*_*bal 9 c# antlr parser-generator lexer
我正在将基于C#的编程语言编译器从手动词法分析器/解析器迁移到Antlr.
Antlr一直给我带来严重的头痛,因为它通常大部分都有效,但是有些小部件没有,而且难以解决.
我发现我的大部分头痛都是由Antlr的词法分析器部分引起的,而不是解析器引起的.然后我注意到parser grammar X;
并意识到也许我可以手动编写lexer,然后是Antlr生成的解析器.
所以我正在寻找关于这个主题的更多文档.我想自定义ITokenStream可以工作,但似乎几乎没有关于这个主题的在线文档...
我发现了怎么样.它可能不是最好的方法,但它似乎确实有效.
ITokenStream
参数ITokenSource
sITokenSource
是一个非常简单的界面 ITokenStream
ITokenSource
为a 的最简单方法ITokenStream
是使用a CommonSourceStream
,它接收一个ITokenSource
参数所以现在我们只需做两件事:
调整语法非常简单.只需删除所有词法分析器声明,并确保将语法声明为parser grammar
.为方便起见,这里张贴了一个简单的例子:
parser grammar mygrammar;
options
{
language=CSharp2;
}
@parser::namespace { MyNamespace }
document: (WORD {Console.WriteLine($WORD.text);} |
NUMBER {Console.WriteLine($NUMBER.text);})*;
Run Code Online (Sandbox Code Playgroud)
请注意,将输出以下文件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();
Run Code Online (Sandbox Code Playgroud)
最后,我们需要定义TokenQueue
.TokenQueue
并非严格必要,但为方便起见,我使用它.它应该有接收词法分析器令牌的方法,以及输出Antlr令牌的方法.因此,如果不使用Antlr本机令牌,则必须实现convert-to-Antlr-token方法.另外,TokenQueue
必须实施ITokenSource
.
请注意,正确设置标记变量非常重要.最初,我遇到了一些问题,因为我算错了CharPositionInLine
.如果这些变量设置不正确,则解析器可能会失败.此外,正常通道(未隐藏)为0.
到目前为止,这似乎对我有用.我希望其他人也觉得它很有用.我愿意接受反馈.特别是,如果您找到更好的方法来解决此问题,请随时发布单独的回复.