小编典典

在Java中编写解释器时切换或if语句

java

当前的工作需要我编写一个程序,以非常小的基本编程语言(行为类似于FORTRAN)读取包含指令的文件,并执行这些指令。基本上,这是我猜语言的简单解释器。它是完全线性的,所有语句都是按顺序定义的,并且只有String和integer变量。我需要找到并定义它们是否在源文件中存在8个关键字和4个算术运算符,并且每一行必须以保留字之一开头。使用这种语言的程序可能看起来像这样:

#COMMENTS
LET.... (declares variables with values)
INTEGER myINT
STRING myString
CALCULATE...
PRINT
PRINTLN
END

我可以使用切换块而不是if循环来查找然后执行所有这些操作吗?我担心的是,在Java
6中,开关不能与Strings一起使用,这是我应该使用的,但是我看不到如何轻松地分配各种int值,以使switch块正常工作。在此先感谢您的任何建议和意见!


阅读 236

收藏
2020-11-30

共1个答案

小编典典

如果您的语言是如此简单,以至于每个语句都以其一行开始并且仅由一个单词标识,那么(如Gray在另一条评论中指出的那样),您可以将每一行中的单词分开,然后将第一个单词与地图进行比较。但是,我建议不要像将单词映射到int然后进行一个大的切换那样,而是将它们映射到对象中,如下所示(由Dave
Newton建议):

interface Directive {
    public void execute(String line);
}

class LetDirective implements Directive {
    public void execute(String line) { ...handle LET directive here... }
}

...define other directives in the same way...

然后定义地图:

private Map<String, Directive> directives = new HashMap<String, Directive>();
directives.put("LET", new LetDirective());
...

然后在您的解析方法中:

int firstSpace = line.indexOf(' ');
String command = line;
if (firstSpace > 0)
    command = line.substring(0, firstSpace);
Directive directive = directives.get(command.toUpperCase());
if (directive != null)
    directive.execute(line);
else
    ...show some error...

每个指令都必须自己解析其余的行,并在其execute()方法中正确处理它。

与开关相比,这样做的好处是您可以处理大量命令,而不必以一个巨大的方法结束,而是每个命令只能使用一个较小的方法。

2020-11-30