【发布时间】:2022-01-17 05:32:16
【问题描述】:
我正在用 Java 开发一个 shell 实现,我正在使用 antlr4 来解析语法。我想将输入的命令一一解析,并将它们存储在一个数组列表中,稍后我将在其中执行命令。
例如,“echo hello;echo world”的输入应该返回一个包含两个 Call 对象的数组列表。如果有帮助,Call 对象代表一个简单的命令。
但是,visitChildren 方法的返回值被最新解析的命令覆盖。如何解析一个命令,将其添加到我的arraylist,然后继续解析下一个命令等等?
CommandConverter.java
package parse;
import java.util.ArrayList;
import app.ApplicationFactory;
import shell.ShellGrammarBaseVisitor;
import shell.ShellGrammarParser;
public class CommandConverter extends ShellGrammarBaseVisitor<Command> {
ApplicationFactory appFactory = new ApplicationFactory();
@Override
public Command visitCommands(ShellGrammarParser.CommandsContext ctx) {
//ArrayList<Command> commands = new ArrayList<>();
return visitChildren(ctx);
}
@Override
public Command visitAtomicCommand(ShellGrammarParser.AtomicCommandContext ctx) {
int childCount = ctx.getChildCount();
String appName = ctx.getChild(0).getText();
ArrayList<String> appArgs = new ArrayList<>();
if(childCount > 1) {
for (int i = 1; i < childCount; i++) {
appArgs.add(ctx.getChild(i).getText());
}
}
return new Call(appFactory.getApplication(appName), appArgs);
}
}
ShellGrammar.g4(部分)
grammar ShellGrammar;
/*
* Parser Rules
*/
commands : atomicCommand (';' atomicCommand )*
atomicCommand : NONSPECIAL (value)*;
value : (NONSPECIAL | DOUBLEQUOTED | SINGLEQUOTED);
/*
* Lexer Rules
*/
NONSPECIAL : ~['";\r\n\t ]+;
DOUBLEQUOTED : '"' (~'"')* '"';
SINGLEQUOTED : '\'' (~'\'')* '\'';
WHITESPACE : [\r\n\t ]+ -> skip ;
【问题讨论】:
标签: java parsing antlr4 visitor-pattern