ANTLR语法的迁移工具 [英] Migration tool for ANTLR grammar

查看:101
本文介绍了ANTLR语法的迁移工具的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下简单语法(查询DSL):

Suppose I have a following simple grammar (query DSL):

grammar TestGrammar;

term : textTerm ;

textTerm : 'Text' '(' T_VALUE '=' STRING+ ')' ;

T_VALUE : 'value' ;
STRING : '"' .+? '"' ;

WS : [ \t\r\n]+ -> skip ;

然后在某个时候,我决定需要更改文本术语格式,例如:

Then at some point I decide that text term format needs to be changed, for example:

Text(value = "123") -> MyText(val = "123")

我应该如何迁移用户使用先前版本的语法生成的现有数据?

How should I approach migrating existing data that users have generated with previous version of grammar?

推荐答案

假设

我们通过为'Text'字符串引入标记TEXT来简化语法.

Assumption

Let's make one simplification of your grammar by introducing token TEXT for 'Text' string.

grammar TestGrammar;

WS : [ \t\r\n]+ -> channel(HIDDEN);  // preserve the whitespaces characters!
T_VALUE : 'value';
STRING : '"' .+? '"';
TEXT : 'Text';

term
    : textTerm;
textTerm
    : TEXT '(' T_VALUE '=' STRING+ ')';

解决方案

现在,我们将利用ANTLRv4工具构建的AST侦听器.这使我们可以遍历AST并使用 Lucas Trzesniewski 在注释中已经提到的TokenStreamRewriter类执行令牌替换.

Solution

Now we will utilize the AST listener built by ANTLRv4 tool. This allows us to traverse AST and perform token replacement with TokenStreamRewriter class already mentioned by Lucas Trzesniewski in comments.

import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStreamRewriter;

public class MigrationTask extends TestGrammarBaseListener {
    private TokenStreamRewriter rewriter;

    public MigrationTask(CommonTokenStream stream) {
        this.rewriter = new TokenStreamRewriter(stream);
    }

    @Override
    public void enterTextTerm(TestGrammarParser.TextTermContext ctx) {
        rewriter.replace(ctx.TEXT().getSymbol(), "MyText");
        rewriter.replace(ctx.T_VALUE().getSymbol(), "val");
    }

    public String getMigrationResult() {
        return rewriter.getText();
    }
}

因此,只要在遍历AST时遇到令牌,我们就会用给定令牌替换它.

So, we substitute given token with its replacement whenever we encounter the token during the traversal of AST.

现在我们可以在给定的ParseTree上执行MigrationTask并获取迁移结果:

Now we can execute MigrationTask on given ParseTree and retrive the migration result:

(...)
CommonTokenStream tokens = new CommonTokenStream(lexer);
TestGrammarParser parser = new TestGrammarParser(tokens);
ParseTree tree = parser.term();
ParseTreeWalker walker = new ParseTreeWalker();
MigrationTask migrationTask = new MigrationTask(tokens);
walker.walk(migrationTask, tree);
String result = migrationTask.getMigrationResult(); // Here we retrive migration result !
(...)

这篇关于ANTLR语法的迁移工具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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