【问题标题】:Generating tree nodes on the fly动态生成树节点
【发布时间】:2013-09-02 09:08:20
【问题描述】:

我有一个 ANTLRv3 语法来转换 AST(由其他语法生成和使用)。

其中一部分是将定义为M:N(即1:5)的范围重写为其实际的列表表示形式——M, M+1, ..., N(即1, 2, 3, 4, 5)

因此,节点^(RANGE s=INT e=INT) 被转换为INT 令牌列表。

我现在做的事情如下:

range
    : ^(RANGE s=INT e=INT) -> { ToSequence(int.Parse($s.text),int.Parse($e.text)) }
    ;

ToSequence 方法看起来像

private ITree ToSequence(int start, int end)
{
    var tree = new CommonTree();

    for (int i = start; i <= end; i++)
    {
        tree.AddChild(new CommonTree(new CommonToken(INT, i.ToString())));
    }

    return tree;
}

它实际上工作正常,将树节点(TIME 1 2 (RANGE 5 10) 3 4) 转换为(TIME 1 2 5 6 7 8 9 10 3 4),但我有点不确定这是否是进行这种转换的正确和惯用方式。

那么,有没有更文明的方式来完成这项任务呢?

【问题讨论】:

    标签: antlr antlr3 abstract-syntax-tree


    【解决方案1】:

    我认为在解析器中执行这样的转换根本不是一个好主意。您的代码缺少任何类型的有效性检查。如果第一个数字大于第二个数字怎么办?如果在下一个处理阶段检测到错误怎么办?那时您已经失去了关于输入的真实结构的知识,因此您无法提供有用的错误消息。

    我强烈建议先构建一个反映您输入的真实结构的树,然后再转换该树。转换后的节点可能会保留对其源节点的引用。

    【讨论】:

    • 嗨!这不是在解析器内部执行的。我有一个解析器、一个转换器和一个消费者。为了简单起见,删除了错误检查——我在这里遇到了 ANTLR 的问题,而不是缺少错误检查。
    • 所以,我这里其实是转换了树,只需要让代码更干净。
    • @Iaroslav Kovtunenko 如果您确信代码是干净的,则无需更改任何内容。对我来说,它看起来不像那样。但这只是我的 2 美分。如果您的问题包含更多真实的应用程序特定信息/代码,我可以为您提供更实用的解决方案。
    • 我不确定的部分代码是否与 ANTLR 相关:树节点构造、令牌构造、将其返回为 ITree/CommonTree/object 等。所以,我真的想知道我是否正确地执行了这部分或有更好的方法来实现它——比如我不知道的静态助手。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多