4

我开始使用 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 教程,但我似乎无法找到有关其工作原理的解释。

提前致谢,

格特-扬

4

3 回答 3

2

在语法上设置LanguageFlags.CreateAst标志后,您必须提供有关如何创建 AST 的附加信息。

你应该能够设置AstContext.Default*Type整个语言,但目前有问题。

  • 设置TermFlags.NoAstNode。Irony 将忽略此节点及其子节点。

  • 设置AstConfig.NodeCreator。这是一个可以做正确事情的代表。

  • 设置AstConfig.NodeType为 AstNode 的类型。这种类型应该是可访问的、实现IAstInit的,并且有一个公共的、无参数的构造函数。在这种情况下,可访问意味着要么publicinternal带有InternalsVisibleTo属性。

于 2012-08-21T23:37:17.587 回答
2

老实说,我遇到了同样的问题并且不理解 Jay Bazuzi 的答案,尽管它看起来像是有效的(也许它已经过时了)。

如果有人像我一样;

我刚刚从 Irony.Interpreter.InterpretedLanguageGrammar课堂上继承了我的语法,并且它有效。此外,任何试图让 AST 工作的人,请确保您的节点是“公共的”:-)

于 2014-03-19T12:16:24.000 回答
0

除了 Jay 和 Erti-Chris 的回复之外,这个帖子也很有用:

https://irony.codeplex.com/discussions/361018

Irony 的创建者在InterpretedLanguageGrammar.BuildAst.

高温高压

于 2014-03-27T18:59:55.623 回答