ANTLR C#如何从树中获取特定节点?

ANTLR C#如何从树中获取特定节点?,c#,parsing,tree,antlr,antlr3,C#,Parsing,Tree,Antlr,Antlr3,我正在解析文本文件。我使用ANTLRWorks编写和检查语法,并使用antlrgue.atlassian.net中的ANTLR3 C#工具编译语法 此时,我可以构建AST并将所有节点打印到控制台(通过递归获取子节点)。 但是,我想根据我的令牌获取特定节点 例如,我有一个带有子名称的节点参数。节点名称依次有一个子项“Johnny”。 在我的应用程序中,我希望有一个带有字段字符串Name=“Johnny”的对象参数 我发现树语法是从AST获取节点所必需的,所以我编写了一个。然而,我找不到一个使用它的

我正在解析文本文件。我使用ANTLRWorks编写和检查语法,并使用antlrgue.atlassian.net中的ANTLR3 C#工具编译语法

此时,我可以构建AST并将所有节点打印到控制台(通过递归获取子节点)。
但是,我想根据我的令牌获取特定节点

例如,我有一个带有子名称的节点参数。节点名称依次有一个子项“Johnny”。
在我的应用程序中,我希望有一个带有字段字符串Name=“Johnny”的对象参数

我发现树语法是从AST获取节点所必需的,所以我编写了一个。然而,我找不到一个使用它的方法

下面是我的选项和示例(简化的)词法分析器和语法分析器规则,它们来自组合语法

options {
language=CSharp3;
TokenLabelType=CommonToken;
output=AST;
ASTLabelType=CommonTree; }

tokens {
StatementT;
ParameterT;
NameT; }

statement : object -> ^(StatementT object);
object : name -> ^(ParameterT name);
name : NAME -> ^(NameT NAME);
ANTLRStringStream input = new ANTLRStringStream(inputString);
myGrammarLexer lexer = new myGrammarLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
myGrammarParser parser = new myGrammarParser(tokens);
var result = parser.statement();
CommonTree tree = (CommonTree)result.Tree;
CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
nodes.TokenStream = tokens;
myTreeGrammar walker = new myTreeGrammar(nodes);
walker.statement();
以下是树语法中的部分(选项和简化规则):

下面是源代码的一部分:

options {
language=CSharp3;
TokenLabelType=CommonToken;
output=AST;
ASTLabelType=CommonTree; }

tokens {
StatementT;
ParameterT;
NameT; }

statement : object -> ^(StatementT object);
object : name -> ^(ParameterT name);
name : NAME -> ^(NameT NAME);
ANTLRStringStream input = new ANTLRStringStream(inputString);
myGrammarLexer lexer = new myGrammarLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
myGrammarParser parser = new myGrammarParser(tokens);
var result = parser.statement();
CommonTree tree = (CommonTree)result.Tree;
CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
nodes.TokenStream = tokens;
myTreeGrammar walker = new myTreeGrammar(nodes);
walker.statement();
正如我所搜索的,下面是在树上行走的代码:

options {
language=CSharp3;
TokenLabelType=CommonToken;
output=AST;
ASTLabelType=CommonTree; }

tokens {
StatementT;
ParameterT;
NameT; }

statement : object -> ^(StatementT object);
object : name -> ^(ParameterT name);
name : NAME -> ^(NameT NAME);
ANTLRStringStream input = new ANTLRStringStream(inputString);
myGrammarLexer lexer = new myGrammarLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
myGrammarParser parser = new myGrammarParser(tokens);
var result = parser.statement();
CommonTree tree = (CommonTree)result.Tree;
CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree);
nodes.TokenStream = tokens;
myTreeGrammar walker = new myTreeGrammar(nodes);
walker.statement();
这一个已经编译好了,但我不知道下一步要去哪里挖掘


您有什么建议?

您使用ANTLR 3有什么特殊原因吗?使这项任务(以及几乎所有其他任务)更加简单。谢谢你的回答。这是我第一次使用ANTLR,所以我开始使用ANTLRWorks来查看视觉表现。最后一个版本的ANTLRWorks是基于ANTLR3的,这就是原因。在ANTLR3和ANTLR4之间切换是否耗时?是为ANTLR 4建造的。从今年早些时候开始,最新版本现在通过分发,并在验证最新版本(昨天上传)后通过更新中心(工具→插件)分发。好了,现在我想我已经将语法改写为antlr4要求。我已经完成了所有步骤。我采用了“Hello”语法,我将“generate listener”和“generate visitor”标记为true,尽管当我点击“build”时,在HelloLexer和HelloParser类中没有生成代码。我做错了什么?这些文件中没有生成的代码。这些文件作为一个位置添加到项目中,您可以在其中向这些类添加其他代码,而无需使用语法中的
@parser::members{}
@lexer::members{}
块。解析器的实际生成文件放置在obj/Debug或obj/Release中,具体取决于当前的构建配置。