问题
I have a grammar that works and parses in the Irony console just fine, but I don't get anything in the AST treeview. I was following along with the BASIC->Javascript article found here: http://www.codeproject.com/Articles/25069/JSBasic-A-BASIC-to-JavaScript-Compiler, but it seems that the Ast stuff has all been moved/removed. I found the Irony.Interpreter .dll, which has some Ast stuff in it, but it seems all tied up in the Expression sample implementation.
What am I missing here? I want to walk my tree and generate source code, and I'm not sure where to start.
I've seen some mention of using the visitor pattern, which I'm fine with, but I don't know how to implement it and run it in a way that Irony likes.
回答1:
Check out the aptly named Sarcasm project for a reference implementation of a grammar, parser, and AST built on Irony. I found this blog entry by the author to be helpful in building the AST.
The following is a general purpose guide to getting the AST up and running.
- Define your grammar (example)
- Create an abstract base class (
MyBaseNode
) deriving fromAstNode
(example). Copy/Paste the methods from the example For each terminal and non-terminal create a new class derived from
MyBaseNode
and- Override
Accept
method (example):
public override void Accept(IMyNodeVisitor visitor) { visitor.Visit(this); }
- Override Init (mostly on terminals) or InitChildren (non-terminals) as appropriate. This is where the AST magic happens.
- Override
Add an interface
IMyNodeVisitor
and add aVisit
method for each class defined in the previous step (example):void Visit(MyDerivedNode1 node);
Set the
ASTNodeType
for each of your terminals and non-terminals in your grammar from step 1.For terminals - (example)
MyTerminal1.AstConfig.NodeType = typeof(MyDerivedNode1);
For non-terminals - (example)
var MyNonTerminal2 = new NonTerminal("MyNonTerminal2", typeof(MyDerivedNode2));
In the grammar enable AST creation: (example)
LanguageFlags = LanguageFlags.CreateAst;
回答2:
In Irony parsing is done in 2 phases. First it creates a parse tree and then it creates your AST tree.
You are only seeing the first step. In order for Irony to create the AST you can:
Tell it how to to map your NonTerminals to AST nodes:
E.g. looking at the Irony sample grammer ExpressionEvaluatorGrammar we see:
var BinExpr = new NonTerminal("BinExpr", typeof(BinaryOperationNode));`
Here the we are telling Irony to map the BinExpr NonTerminal to a BinaryOperationNode which is our AST node.
Make it generate the AST when parsing:
When you set this flag the AST tree will be generated when you parse.
this.LanguageFlags = LanguageFlags.CreateAst;
The root of your AST tree will then be:
parseTree.Root.AstNode
I found this source a great starting point.
来源:https://stackoverflow.com/questions/15012865/how-do-i-work-with-the-ast-in-irony-now