如何合并两个AST? [英] How to merge two ASTs?

查看:36
本文介绍了如何合并两个AST?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个工具来合并某些源代码的不同版本.给定相同源代码的两个版本,想法是解析它们,生成各自的抽象源树 (AST),最后将它们合并为一个保持语法一致性的输出源——词法分析器和解析器是问题 ANTLR:如何跳过多行注释.

I'm trying to implement a tool for merging different versions of some source code. Given two versions of the same source code, the idea would be to parse them, generate the respective Abstract Source Trees (AST), and finally merge them into a single output source keeping grammatical consistency - the lexer and parser are those of question ANTLR: How to skip multiline comments.

我知道有类 ParserRuleReturnScope 可以帮助...但是 getStop()getStart() 总是返回 null :-(

I know there is class ParserRuleReturnScope that helps... but getStop() and getStart() always return null :-(

这是一个片段,说明了我如何修改我的 perser 以打印规则:

Here is a snippet that illustrates how I modified my perser to get rules printed:

parser grammar CodeTableParser;

options {
    tokenVocab = CodeTableLexer;
    backtrack = true;
    output = AST;
}

@header {
    package ch.bsource.ice.parsers;
}

@members {
    private void log(ParserRuleReturnScope rule) {
        System.out.println("Rule: " + rule.getClass().getName());
        System.out.println("    getStart(): " + rule.getStart());
        System.out.println("    getStop(): " + rule.getStop());
        System.out.println("    getTree(): " + rule.getTree());
    }
}

parse
    : codeTabHeader codeTable endCodeTable eof { log(retval); }
    ;

codeTabHeader
    : comment CodeTabHeader^ { log(retval); }
    ;

...

推荐答案

在你的解析器代码中对 log(retval) 的调用看起来会发生在规则的末尾,但它是不是.您需要将调用移动到 @after 块中.

The call to log(retval) in your parser code looks like it's going to happen at the end of the rule, but it's not. You'll want to move the call into an @after block.

我更改了 log 以吐出一条消息以及范围信息,并将对它的调用添加到我自己的语法中,如下所示:

I changed log to spit out a message as well as the scope information and added calls to it to my own grammar like so:

script    
    @init {log("@init", retval);}
    @after {log("@after", retval);}
    : statement* EOF  {log("after last rule reference", retval);} 
        -> ^(STMTS statement*) 
    ;

解析测试输入产生以下输出:

Parsing test input produced the following output:

Logging from @init
    getStart(): [@0,0:4='Print',<10>,1:0]
    getStop(): null
    getTree(): null
Logging from after last rule reference
    getStart(): [@0,0:4='Print',<10>,1:0]
    getStop(): null
    getTree(): null
Logging from @after
    getStart(): [@0,0:4='Print',<10>,1:0]
    getStop(): [@4,15:15='<EOF>',<-1>,1:15]
    getTree(): STMTS

after 块中的调用同时填充了 stoptree 字段.

The call in the after block has both the stop and tree fields populated.

我不能说这是否会对您的合并工具有所帮助,但我认为这至少可以让您解决半填充范围对象的问题.

I can't say whether this will help you with your merging tool, but I think this will at least get you past the problem with the half-populated scope object.

这篇关于如何合并两个AST?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆