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

我是在正确的轨道上还是完全偏离了轨道?

4

2 回答 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。Tree walkers 与解析器语法非常相似。

最大的区别在于,虽然解析器语法必须完全匹配,但树语法只需要匹配树的一部分。

expr规则中,我们可以看到它匹配任何具有标记PLUSorSTAR或的树INT

我们可以看到我们正在匹配树,因为我们使用的是 Antlr 的树语法#(...)

PLUSandSTAR树也匹配 2 条 expr 规则。每个 expr 规则都分配了一个名称,因此我们可以使用它来评估表达式。与解析器语法类似,我们可以将 C# 代码放入由{...}.

另请注意,在此示例中,我们展示了如何从 TreeWalker 规则返回值,我们使用语法return [...]

要调用 tree walker,您可以创建它,然后将其称为顶级规则。我将从 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);
于 2010-02-11T16:05:17.190 回答
1

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

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

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

于 2010-02-12T16:02:31.610 回答