Tree 未创建ANTLR3异质节点

Tree 未创建ANTLR3异质节点,tree,antlr,nodes,antlr3,heterogeneous,Tree,Antlr,Nodes,Antlr3,Heterogeneous,我正在尝试根据此处提供的示例创建异构树: 我创建了一个语法文件,如下所示: grammar T; options { language=CSharp3; ASTLabelType=CommonTree; output=AST; TokenLabelType=CommonToken; k=3; } tokens { ROOT; UNARY_MIN; } @lexer::header { using System; using Syste

我正在尝试根据此处提供的示例创建异构树:

我创建了一个语法文件,如下所示:

grammar T; 

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

tokens { 
  ROOT; 
  UNARY_MIN; 
} 

@lexer::header 
{
  using System;
  using System.Text;
  using System.Collections;
  using System.Collections.Generic;
  using ANTLRSandbox.Criteria;
}

@parser::header 
{
  using System;
  using System.Text;
  using System.Collections;
  using System.Collections.Generic;
  using ANTLRSandbox.Criteria;
}


@parser::namespace { ANTLRSandbox } 
@lexer::namespace { ANTLRSandbox } 


public
parse 
  :  exp EOF -> ^(ROOT<RootNode> exp) 
  ; 

exp 
  :  addExp 
  ; 

addExp 
  :  mulExp (('+'<PlusNode> | '-'<MinusNode>)^ mulExp)* 
  ; 

mulExp 
  :  unaryExp (('*' | '/')^ unaryExp)* 
  ; 

unaryExp 
  :  '-' atom -> ^(UNARY_MIN atom) 
  |  atom 
  ; 

atom 
  :  Number 
  |  '(' exp ')' -> exp 
  ; 

Number 
  :  ('0'..'9')+ ('.' ('0'..'9')+)? 
  ; 

Space  
  :  (' ' | '\t' | '\r' | '\n'){Skip();} 
  ; 
PlusNode
MinusNode
RootNode
相同,因此我不会在这里发布它们

下面是我如何创建实际的树:

    string s = "(12.5 + 56 / -7) * 0.5";

    ANTLRStringStream Input = new ANTLRStringStream(s);
    TLexer Lexer = new TLexer(Input);
    CommonTokenStream Tokens = new CommonTokenStream(Lexer);
    TParser Parser = new TParser(Tokens);

    TParser.parse_return ParseReturn = Parser.parse();
    CommonTree Tree = (CommonTree)ParseReturn.Tree;
代码运行时没有任何错误,但当我“监视”
Tree
对象时,它的所有节点都是
CommonTree
类型,我在
PlusNode
中放置的所有断点都将丢失,
MinusNode
RootNode
构造函数

我遵循了ANTLR3 wiki页面中提供的示例,但在web上找不到任何示例。我知道他们打算在某个时候放弃这种方法(在ANTLR3预览说明中找到),但这种实现更适合我(我需要根据语法上下文创建不同的对象类型)

所以。。。有什么提示吗?我错过什么了吗?将其放入语法定义文件的一些选项/标志

谢谢!
D.

我从来没有很幸运地得到过这些操作符
<…>
在使用内联树运算符时起作用(
^
表示根,而
表示省略规则)。我建议您在解析器规则的右侧使用重写规则(
..->^(…)
),然后在重写规则中只定义自定义节点,
,而不是像Wiki提到的那样在两侧(!):我怀疑Wiki信息有点过时。我知道这样的表达式规则使用内联运算符比使用重写规则更具可读性

我对C#不是很流利,所以这里有一个Java演示:

T.g
语法T;
选项{
ASTLabelType=CommonTree;
输出=AST;
} 
代币{
根;
一元人民币;
}
@成员{
公共静态类RootNode扩展了CommonTree{
公共根节点(令牌t){Token=t;}
公共根节点(int ttype){super(新的CommonToken(ttype,“ROOT”);}
公共RootNode(RootNode){super(node);}
公共树dupNode(){返回新根节点(this);}
公共字符串toString(){return“RootNode=“+token.getText();}
}
公共静态类节点扩展了CommonTree{
公共节点(令牌t){Token=t;}
公共MinusNode(MinusNode){super(node);}
公共树dupNode(){返回新的MinusNode(this);}
公共字符串toString(){return“MinusNode=“+token.getText();}
}
公共类PlusNode扩展了CommonTree{
公共PlusNode(Token t){Token=t;}
公共PlusNode(PlusNode节点){super(node);}
公共树dupNode(){返回新的PlusNode(this);}
公共字符串toString(){return“PlusNode=“+token.getText();}
}
}
作语法分析
:exp EOF->^(根exp)
; 
经验
:addExp
; 
加法器
:(mulExp->mulExp)(“+”m=mulExp->^(“+”$m$addExp)
|'-'m=mulExp->^('-'m$addExp)
)* 
; 
mulExp
:unaryExp((“*”|“/”)^unaryExp)*
; 
一元表达式
:“-”原子->^(一元最小原子)
|原子
; 
原子
:号码
|“(“exp”)”->exp
; 
数
:  ('0'..'9')+ ('.' ('0'..'9')+)? 
; 
空间
:(“”|’\t’|’\r’|’\n’{skip();}
; 
主类
import org.antlr.runtime.*;
导入org.antlr.runtime.tree.*;
导入org.antlr.stringtemplate.*;
公共班机{
私有静态无效遍历(CommonTree树,整数缩进){
if(tree==null)返回;
对于(int i=0;i”+tree.getText());
对于(int i=0;i
运行演示:
java-cp antlr-3.3.jar org.antlr.Tool T.g
javac-cp antlr-3.3.jar*.java
java-cp.:antlr-3.3.jar Main
将打印:

TParser$RootNode->ROOT
TParser$MinusNode->-
org.antlr.runtime.tree.CommonTree->3
tPasser$PlusNode->+
org.antlr.runtime.tree.CommonTree->2
org.antlr.runtime.tree.CommonTree->1
。基本上,在指定节点类型时,必须显式使用
node=
;您不能依赖文档中的隐式行为。例如,您需要更改以下内容:

parse 
  :  exp EOF -> ^(ROOT<RootNode> exp)
  ; 
parse
:exp EOF->^(根exp)
; 
……为此:

parse 
  :  exp EOF -> ^(ROOT<node=RootNode> exp)
  ; 
parse
:exp EOF->^(根exp)
; 

在我自己的语法中,一旦我修改了重写规则,解析器最终会输出异构节点。

对其进行了测试。我实际上只复制和修改了c#(字母大小写和代码中的一些小东西)所需的东西。它从一开始就可以编译,但是当我转储树时,所有节点都是CommonTree类型的。不知道还能做什么。。。我想我会选择TreeAdaptor方法,尽管我不是它的超级粉丝!无论如何,谢谢你的努力@dcg,这是不幸的:(.也许
CSharp2
可以工作?(注意,它的运行时类与
CSharp3
)不同。我可能会自己尝试一下
CSharp3
,尽管我在Mono和Ubuntu上没有太多的运气(
CSharp2
在我的系统上工作…).我知道。我必须使用c#-我正在处理的项目的前一个版本是用antlr2/chsarp制作的,它成功了。我们需要做一次升级,我认为我可以遵循相同的模式。无论如何,用普通的方法!我想你最终不会想出如何让c#3目标生成异构节点,是吗?accepted答案并没有真正回答这个问题。我遇到了同样的困难。不,运气不好。我最终在
Create
m中的一家工厂使用了树适配器(
CommonTreeAdaptor
parse 
  :  exp EOF -> ^(ROOT<node=RootNode> exp)
  ;