我开始使用Irony(版本Irony_2012_03_15),但在尝试生成AST时我很快就陷入困境。下面是一个完全划分的语言,抛出异常:
[Language("myLang", "0.1", "Bla Bla")]
public class MyLang: Grammar {
public NModel()
: base(false) {
var number = TerminalFactory.CreateCSharpNumber("number");
var binExpr = new NonTerminal("binExpr", typeof(BinaryOperationNode));
var binOp = new NonTerminal("BinOp");
binExpr.Rule = number + binOp + number;
binOp.Rule = ToTerm("+");
RegisterOperators(1, "+");
//MarkTransient(binOp);
this.Root = binExpr;
this.LanguageFlags = Parsing.LanguageFlags.CreateAst; // if I uncomment this line it throws the error
}
}
一旦我取消注释最后一行,它就会在语法资源管理器中抛出NullReferenceException,或者当我想解析一个测试时。错误发生在AstBuilder.cs第96行:
parseNode.AstNode = config.DefaultNodeCreator();
DefaultNodeCreator是尚未设置的委托。
我尝试用MarkTransient等设置东西,但没有骰子。
有人可以帮助我漂浮在这里吗?我可能会遗漏一些明显的东西。在整个网络上寻找AST教程,但我似乎无法找到有关其工作原理的解释。
提前致谢,
格特 - 扬
答案 0 :(得分:1)
在语法上设置LanguageFlags.CreateAst
标志后,您必须提供有关如何创建AST的其他信息。
您应该可以为整个语言设置AstContext.Default*Type
,但目前已经过了错误。
设置TermFlags.NoAstNode
。反讽会忽略这个节点及其子节点。
设置AstConfig.NodeCreator
。这是一个可以做正确事情的代表。
将AstConfig.NodeType
设置为AstNode的类型。此类型应该是可访问的,实现IAstInit
,并具有public,no-parameters构造函数。在这种情况下可访问意味着具有public
属性的internal
或InternalsVisibleTo
。
答案 1 :(得分:1)
说实话,我遇到了同样的问题,并且不理解Jay Bazuzi的回答,虽然它看起来像是有效的(也许它已经过时了)。
如果有人喜欢我;
我刚从Irony.Interpreter.InterpretedLanguageGrammar
课程继承了我的语法,但它确实有效。此外,任何人都试图让AST工作,确保你的节点是"公共" : - )
答案 2 :(得分:0)
除了Jay和Erti-Chris的回答之外,这个帖子也很有用:
https://irony.codeplex.com/discussions/361018
Irony的创建者指出InterpretedLanguageGrammar.BuildAst
中的相关配置代码。
HTH