ANTLR - 为 AST 编写树语法

3

我有一个由我的语法文件输出的Lua代码的AST,目前它为我执行解析和词法分析。我想要添加一个树形语法到其中,但是因为我使用的是C#,我不确定该如何实现。当你已经编写了解析器和词法分析器时,生成树形语法代码的基本过程是什么?

更新:我有以下语法文件:

tree grammar LuaGrammar;

options {
  backtrack=true;
  language=CSharp2;
  //output=AST;
  tokenVocab=Lua;
  filter=true;
  ASTLabelType=CommonTree;
}
@lexer::namespace{/*my namespace*/}
@parser::namespace{/*my namespace*/}

dummyRule
    :   ^('=' x=. y=.) {};

我的主要语法文件和这个文件放在同一个目录下,生成没有问题。但是,在尝试编译这个文件时,我遇到了以下错误:

[02:54:06] error(143): C:\Users\RCIX\Desktop\AguaLua\Project\trunk\AguaLua\AguaLua\ANTLR Data\LuaGrammar.g:12:18: unknown or invalid action scope for tree grammar: lexer
[02:54:06] error(143): C:\Users\RCIX\Desktop\AguaLua\Project\trunk\AguaLua\AguaLua\ANTLR Data\LuaGrammar.g:13:19: unknown or invalid action scope for tree grammar: parser

我是不是走在正确的道路上,或者完全偏离了轨道?


你使用的Antlr版本是什么? - chollida
2个回答

2

回到我通常使用的计算器语法的例子:

这是您声明Tree Walker类的方式

class CalcTreeShaker extends TreeParser;

expr returns [float r]
{
float a,b;
r=0;
}
:   #(PLUS a=expr b=expr)   {r = a+b;}
|   #(STAR a=expr b=expr)   {r = a*b;}
|   i:INT           {r = Convert.ToSingle(i.getText());}
;

这里我们有一个名为expr的树规则。树遍历器非常类似于解析器语法。
最大的区别在于,虽然解析器语法必须完全匹配,但树语法只需要匹配部分树。
expr规则中,我们可以看到它匹配任何具有令牌PLUSSTARINT的树。
我们可以看到我们正在匹配树,因为我们使用了Antlr的树语法#(...)PLUSSTAR树也匹配两个expr规则。每个expr规则都被赋予一个名称,以便我们可以用它来计算表达式。与解析器语法类似,我们可以在由{...}定义的块中放置C#代码。
此外,请注意,在此示例中,我们显示了如何从TreeWalker规则返回值,我们使用语法return[...]
要调用树遍历器,您需要创建它,然后调用其顶级规则。我将从Antlr示例中复制这个:)
// Get the ast from your parser.
CommonAST t = (CommonAST)parser.getAST();

// Create the Tree Shaker
CalcTreeWalker walker = new CalcTreeWalker();
CalcParser.initializeASTFactory(walker.getASTFactory());

// pass the ast to the walker and call the top level rule.
float r = walker.expr(t);

这非常有帮助,但目前我正在尝试获取一个有效的文件,以便我可以说服ANTLR将其编译成一些代码,也许我漏掉了什么... - RCIX

1

我没有遇到过这个错误,但是有两件事情我会尝试。

1)删除@lexer和@parser命名空间行。

2)如果它们是必需的,则将它们移动到语法的Tokens {...}部分之后,即在规则之前。


好的,但你可以编辑你的新信息 :) 我可能需要找到树形语法规则的等效语句... - RCIX
修好了,我会从这里开始慢慢摸索的 :) - RCIX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接