当前位置: 首页 > 知识库问答 >
问题:

ANTLR语法迁移工具

范宏大
2023-03-14

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

grammar TestGrammar;

term : textTerm ;

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

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

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

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

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

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

共有1个答案

宦兴朝
2023-03-14

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

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在评论中已经提到的TokenStreamReWrit执行令牌替换。

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遍历过程中遇到令牌时,我们都会用它的替换替换给定的令牌。

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

(...)
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,但现在不得不将旧版本的语法迁移到最新版本。我正在尝试为C#目标生成lexer和解析器。我在迁移下面看到的开始规则上卡住了。 我得到以下错误。语法错误:

  • 问题内容: 因此,我一直在使用ANTLRv3.4在Eclipse中进行语法编写,并且已经编写了一个有效的语法,我想确保在编辑该语法时一切仍然有效。我可以每次都进入口译员的行列,但这似乎很浪费时间。 问题:我已经读过关于gunit的信息,但是它提供了下载gUnit的链接:(http://antlr.org/hudson/job/gUnit/org.antlr $ gunit / lastSucces

  • 在一个类中,我以前会像这样创建一个共享实例: Swift 3.0迁移工具似乎已将代码块更改为: 我得到错误。这里发生了什么?为什么创建了新的var?

  • 名称: aof_to_pika 位置: pika bin目录下 目的: 方便Redis数据到Pika的迁移 背景: Pika兼容Redis协议,所以任何使用于Redis的迁移工具同样也适用于Pika,Redis-cli本身提供了一个pipe参数来完成Redis到Redis的数据迁移。该工具的实现方式为读取待迁移Redis的aof文件并批量发送到目的Redis。Berry借鉴这种方式,并增加了如下改

  • 数据库迁移工具 首先通过 composer 安装 composer require topthink/think-migration 注意事项,不支持修改文件配置目录 在命令行下运行查看帮助,可以看到新增的命令 php think migrate migrate:create Create a new migration migrate:rollback Rollback t

  • 项目名称: pika_port 项目作者: AlexStocks 适用版本: 3.1 和 2.x 项目地址: https://github.com/ipixiu/pika-tools https://github.com/Axlgrep/pika-tools 长期维护地址需自行编译 二进制包: https://github.com/ipixiu/pika-port-bin 功能: 将Pika中的数