Antlr 异构AST问题

Antlr 异构AST问题,antlr,antlr3,Antlr,Antlr3,我检查了ANTLR中的异构树(使用ANTLRWorks 1.4.2) 下面是我在ANTLR中已经完成的示例 grammar test; options { language = java; output = AST; } tokens { PROGRAM; VAR; } @members { class Program extends CommonTree { public Program(int ttype) {

我检查了ANTLR中的异构树(使用ANTLRWorks 1.4.2)

下面是我在ANTLR中已经完成的示例

grammar test;

options {
    language = java;
    output = AST;
}

tokens {
    PROGRAM;
    VAR;
}

@members {
    class Program extends CommonTree {
        public Program(int ttype) {
            token = new CommonToken(ttype, "<start>");
        }
    }
}

start
    :    program var function
        // Works fine:
        //->    ^(PROGRAM program var function)

        // Does not work (described below):
        ->    ^(PROGRAM<Program> program var function)
    ;

program
    :    'program'! ID ';'!
    ;

var
    :    TYPE^ ID ';'!
    ;

function
    :    ID '('! ')'! ';'!
    ;

TYPE
    :    'int'
    |    'string'
    ;

ID
    :    ('a'..'z' | 'A'..'Z')+
    ;

WHITESPACE
    :    (' ' | '\t' '\n'| '\r' | '\f')+ {$channel = HIDDEN;}
    ;
当我使用重写规则
^(程序变量函数)
时,ANTLR会绊倒,我得到如下AST:

然而,当我使用此重写规则
^(程序变量函数)
时,它可以工作:

  • 谁能解释一下我哪里错了吗?坦率地说,我并不真正了解异构树的概念,也不知道如何在ANTLR中使用
    语法

  • grammar test;
    
    options {
        language = java;
        output = AST;
    }
    
    tokens {
        PROGRAM;
        VAR;
    }
    
    @members {
        class Program extends CommonTree {
            public Program(int ttype) {
                token = new CommonToken(ttype, "<start>");
            }
        }
    }
    
    start
        :    program var function
            // Works fine:
            //->    ^(PROGRAM program var function)
    
            // Does not work (described below):
            ->    ^(PROGRAM<Program> program var function)
        ;
    
    program
        :    'program'! ID ';'!
        ;
    
    var
        :    TYPE^ ID ';'!
        ;
    
    function
        :    ID '('! ')'! ';'!
        ;
    
    TYPE
        :    'int'
        |    'string'
        ;
    
    ID
        :    ('a'..'z' | 'A'..'Z')+
        ;
    
    WHITESPACE
        :    (' ' | '\t' '\n'| '\r' | '\f')+ {$channel = HIDDEN;}
        ;
    
  • r0
    r1
    是什么意思(第一张图片)


  • 我不知道这些
    r0
    r1
    是什么意思:我不使用AntlWorks进行调试,因此无法对此发表评论

    而且,
    language=java导致ANTLR 3.2产生错误:

    错误(10):内部错误:没有这样的组文件java.stg

    错误(20):找不到代码生成模板java.stg
    错误(10):内部错误:没有这样的组文件java.stg

    错误(20):找不到代码生成模板java.stg

    Antlr3.2希望它是
    language=Java(大写“J”)。但是,默认情况下,目标是Java,因此,请注意完全删除
    language=…

    现在,关于你们的问题:我不能复制它。正如我提到的,我用Antlr3.2测试了它,并删除了
    language=java语法的一部分,然后一切按我的预期进行

    启用重写规则
    ->^(程序变量函数)
    产生以下ATS:

    当启用重写规则
    ->^(程序变量函数)
    时,将创建以下AST:

    我使用以下类测试了这两个重写规则:

    import org.antlr.runtime.*;
    import org.antlr.runtime.tree.*;
    import org.antlr.stringtemplate.*;
    
    public class Main {
        public static void main(String[] args) throws Exception {
            ANTLRStringStream in = new ANTLRStringStream("program foobar; int foo; bar();");
            testLexer lexer = new testLexer(in);
            CommonTokenStream tokens = new CommonTokenStream(lexer);
            testParser parser = new testParser(tokens);
            testParser.start_return returnValue = parser.start();
            CommonTree tree = (CommonTree)returnValue.getTree();
            DOTTreeGenerator gen = new DOTTreeGenerator();
            StringTemplate st = gen.toDOT(tree);
            System.out.println(st);
        }
    }
    

    图像是使用(当然还有
    Main
    类的输出)生成的。

    AFAIK,您不能只是混合
    <…>内部重写规则:您可以选择
    output=AST或<代码>输出=模板
    选项{…}
    部分中定义,而不是两者都定义。因此,您要么生成AST,要么使用StringTemplate引擎生成(源)代码。你到底想在这里干什么?你的目标是什么?@Bart谢谢你的评论和编辑!基于,我可以混合
    和重写规则。我的目标是构建异构AST(作为任务的一部分)。据我所知(这很棘手!),我必须实现自己的树和AST节点。此时不需要
    Java
    代码(除了
    @members
    部分中的代码)。花了两天的时间,到目前为止没有运气。啊哈,这是新的v3.1+语法:我的ANTLR书(符合v3.0)只提到了
    <…>
    output=template
    结合使用。谢谢你的链接。我现在没有时间去看,但我会晚些时候(可能是明天)再给你回电。@Bart谢谢你。你指的是什么书?我有一本-«权威的ANTLR参考»(实用程序员),虽然没有找到任何有用的信息。是的,对不起,“ANTLR书”确实是来自Prag Prog的权威的ANTLR参考。在那里,
    <…>仅在第9章中使用,即使用模板和语法生成结构化文本,您需要在选项部分设置
    output=template
    。这个新功能还没有处理好,阿福。首先,谢谢你的时间和努力,巴特。我很感激!其次。我(作业)全错了。我不应该在
    @members
    部分中进行AST构造,而是在单独的
    .java
    类中进行AST构造。最后,事实证明,
    ANTLRWorks
    不适合这样的任务。我花了6天的时间才尝试将AntlWorks从
    AntlWorks
    完全迁移到旧的良好命令行界面。:-)另外,出于某种原因,
    ANTLRWorks
    将从
    DebugParser
    继承
    MyGrammarParser
    ,而不是
    Parser
    。(但是,尽管如此,
    ANTLRWorks
    处理其他一切都很好)。关于
    language=java,你是对的。在处理Java时,最好不要使用它。接下来,
    ->^(PROGRAM-var-function)
    也像我预期的那样工作(但是,同样,不是在
    antlworks
    )。@Little Jeans,不客气。是的,我只用ANTLRWorks来编辑语法。生成lexer/parser并调试它们,我也从命令行执行。