j3d*_*j3d 5 java parsing antlr abstract-syntax-tree lexer
我正在尝试实现一个合并某些源代码的不同版本的工具.给定相同源代码的两个版本,想法是解析它们,生成相应的抽象源树(AST),最后将它们合并到单个输出源中,保持语法一致性 - 词法分析器和解析器是ANTLR的问题:如何跳过多行注释.
我知道有一流的ParserRuleReturnScope帮助...但getStop()并getStart()始终返回null :-(
这是一个片段,说明了我如何修改我的perser来打印规则:
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); }
;
...
Run Code Online (Sandbox Code Playgroud)
解析器代码中的调用log(retval)看起来像是将在规则末尾发生,但事实并非如此。您需要将呼叫移至一个@after块中。
我改为log吐出一条消息以及范围信息,并将对其的调用添加到我自己的语法中,如下所示:
script
@init {log("@init", retval);}
@after {log("@after", retval);}
: statement* EOF {log("after last rule reference", retval);}
-> ^(STMTS statement*)
;
Run Code Online (Sandbox Code Playgroud)
解析测试输入产生以下输出:
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
Run Code Online (Sandbox Code Playgroud)
块中的调用after已填充stop和tree字段。
我不能说这是否会帮助您使用合并工具,但我认为这至少会让您解决半填充范围对象的问题。