Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ANTLR语法迁移工具_Antlr_Grammar_Antlr4 - Fatal编程技术网

ANTLR语法迁移工具

ANTLR语法迁移工具,antlr,grammar,antlr4,Antlr,Grammar,Antlr4,假设我有以下简单语法(查询DSL): 然后在某个时候,我决定需要更改文本术语格式,例如: Text(value = "123") -> MyText(val = "123") 如何迁移用户使用以前版本的语法生成的现有数据? 让我们通过为'TEXT'字符串引入标记TEXT来简化语法 语法测试语法; WS:[\t\r\n]+->频道(隐藏);//保留空白字符! T_值:“值”; 字符串:“'”.+?“'”; 文本:“文本”; 学期 :textTerm; 文本术语 :文本“(“T_值”=“字符

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

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

Text(value = "123") -> MyText(val = "123")
如何迁移用户使用以前版本的语法生成的现有数据?

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

语法测试语法;
WS:[\t\r\n]+->频道(隐藏);//保留空白字符!
T_值:“值”;
字符串:“'”.+?“'”;
文本:“文本”;
学期
:textTerm;
文本术语
:文本“(“T_值”=“字符串+”)”;
解决方案 现在我们将利用ANTLRv4工具构建的AST侦听器。这允许我们遍历AST并使用Lucas Trzesniewski在评论中已经提到的
TokenStreamRewriter
类执行令牌替换

import org.antlr.v4.runtime.CommonTokenStream;
导入org.antlr.v4.runtime.TokenStreamRewriter;
公共类迁移任务扩展了TestGrammarBaseListener{
私有令牌流重写器;
公共迁移任务(CommonTokenStream){
this.rewriter=新令牌流重写器(流);
}
@凌驾
公共无效enterTextTerm(TestGrammarParser.TextTermContext ctx){
rewriter.replace(ctx.TEXT().getSymbol(),“MyText”);
重写器.replace(ctx.T_VALUE().getSymbol(),“val”);
}
公共字符串getMigrationResult(){
返回rewriter.getText();
}
}
因此,每当我们在遍历AST时遇到给定的令牌时,我们就用它的替换来替换它

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

(…)
CommonTokenStream令牌=新的CommonTokenStream(lexer);
TestGrammarParser=新的TestGrammarParser(令牌);
ParseTree=parser.term();
ParseTreeWalker=新的ParseTreeWalker();
MigrationTask MigrationTask=新的MigrationTask(令牌);
walker.walk(迁移任务,树);
String result=migrationTask.getMigrationResult();//这里我们检索迁移结果!
(...)

对于这些简单的更改,
TokenStreamRewriter
正是您所需要的。谢谢,@lucastzesniewski。我终于尝试了这个,它似乎成功了。谢谢你,它成功了!为了保留空格,我只需要做一个更改:对空格使用
频道(隐藏)
而不是
跳过
。@AndrewLogvinov:不客气!是的,
频道(隐藏)
,谢谢。我将用这一点为子孙后代简化答案。
Text(value = "123") -> MyText(val = "123")