2011-02-14 75 views
7

我在Irony中定义了一个简单的语法,并生成了一个很好的紧凑AST。反讽:评估AST节点的教程?

现在,我试图找出如何评价它。问题是,我找不到关于如何做到这一点的任何教程。

我定义了仅有2 AST节点:

class TagListNode : AstNode 
{ 
    public override void Init(ParsingContext context, ParseTreeNode treeNode) 
    { 
     base.Init(context, treeNode); 
     AsString = "TagList"; 
     foreach (var node in treeNode.ChildNodes) 
      AddChild(null, node); 
    } 

    public override void EvaluateNode(Irony.Interpreter.EvaluationContext context, AstMode mode) 
    { 
     foreach (var node in ChildNodes) 
      node.EvaluateNode(context, AstMode.Read); 
    } 
} 

class TagBlockNode : AstNode 
{ 
    public AstNode Content; 

    public override void Init(ParsingContext context,ParseTreeNode treeNode) 
    { 
     base.Init(context, treeNode); 
     AsString = treeNode.ChildNodes[0].FindTokenAndGetText(); 
     Content = AddChild(null, treeNode.ChildNodes[1]); 
    } 

    public override void EvaluateNode(EvaluationContext context, AstMode mode) 
    { 
     context.Write(string.Format("<{0}>", AsString)); 
     Content.EvaluateNode(context, AstMode.Read); 
     context.Write(string.Format("</{0}>", AsString)); 
    } 
} 

,这将产生以下输出:

<html><head><title></title></head><body><h1></h1><p></p><p></p></body></html>3.14159265358979 

而我想要的输出是:

<html> 
    <head> 
     <title>page title</title> 
    </head> 
    <body> 
     <h1>header</h1> 
     <p>paragraph 1</p> 
     <p>3.14159265358979</p> 
    </body> 
</html> 

我不不认为我应该使用Context.Write()。示例显示将内容推送到context.Data并将其弹出...但我不太确定这是如何工作的。

我在猜测pi最终会加固,因为它会自动推送到context.Data,然后一个元素在最后弹出?我不太确定。

有些指针或指向教程的链接会很好。

另外,我该如何处理不同的节点类型?每个“标签”可以有4种不同类型的内容:另一个标签,一个字符串文字,一个变量或一个数字。我是否应该在EvaluateNode方法中写入诸如if(node is StringLiteral) ....的东西或什么?


我发现this one,但他们只是在AST循环,不采取EvaluateNode优势。

然后this one其中取代在数据堆栈中的单个值...但并没有真正解释如何输出或任何东西。


要清楚,我特别想知道如何重写EvaluateNode方法Irony.Ast.AstNode做我想做的。


好啦,我已经跟踪该珍闻在结束这一行:这是包含在默认的评估程序

if (EvaluationContext.HasLastResult) 
     EvaluationContext.Write(EvaluationContext.LastResult + Environment.NewLine); 

....也许它运作良好的计算器应用程序,但不是我的。试图找出如何绕过脚本解释器,但是我不知道如何设置全局变量。

回答

0

遍历AST结构的最好方法是实现访问者pattern

也许这个link可以帮到你。

+1

对不起,这些链接都不是非常有用...可以肯定的是,Irony已经采用了访客模式,而mgrammar!=讽刺。 – mpen 2011-02-14 08:42:38