<分区>
我想弄清楚从哪里开始这个项目。也许有人可以引导我朝着正确的方向前进。
有人给了我一种小语言,我必须为其编写解释器。该语言由括号中的表达式组成:
(integer integer operator)
或由以下形式的表达式组成的算术 IF 语句:
IF exp1 exp2 exp3 exp4
如果 exp1 为负,则返回 exp2,
如果 exp1 为零,则返回 exp3,
如果 exp1 为正,则返回 exp4。
运算符是 + 或 x(分别用于加法和乘法)。
我必须一起实现一个扫描器/解析器,然后是将输出结果的解释器。解释器部分并不困难,但我无法弄清楚如何开始扫描/解析过程。
我从使用 Java 开始,让一个 Scanner 对象收集输入并将其存储在一个字符串中。然后我将字符串拆分为一个字符串数组,不使用任何分隔符(以便每个单个字符、符号、空格等都存储在它自己的字符串索引中)。这可能不是最好的方法,因为我不知道从这里去哪里。我无法掌握的部分是如果不遵循此语法如何返回错误,或者如何检测括号和/或 IF 等。
这是我在上一段中描述的代码片段:
public void run() {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String sLine = sc.nextLine();
String[] scanned = sLine.split("");
输入示例:
(7 2 +)
Output: 9
IF (2 -2 +) (5 2 +) (5 -2 x) (5 2 x)
Output: -10
如果有人对我有好的方向,请分享。 :)
我认为使用 ANTLR、JavaCC、SampleCC 或其他解析器生成器工具无异于使用大锤来破解坚果。如果语法定义中没有递归,那么几个方法就足够了。下面的代码给出了一个基本的想法(它可能无法编译或工作,我是从头开始写的,以说明如何开始):
public int parse(String input) {
Scanner scanner = new Scanner(input);
return consumeLine(scanner);
}
public int consumeLine(Scanner scanner) {
if( scanner.hasNext("(") ) {
return consumeExpression(scanner);
} else if( scanner.hasNext("IF") ) {
return consumeIf(scanner);
}
}
public int consumeExpression(Scanner scanner) {
scanner.next("(");
int a = scanner.nextInt();
int b = scanner.nextInt();
String op = scanner.next("[+-/*]");
scanner.next(")");
if( "+".equals(op) ) {
return a + b;
} else if( "-".equals(op) ) {
return a - b;
} ...
throw new RuntimeException("parsing error");
}
public int consumeIf(Scanner scanner) {
scanner.next("IF");
int exp1 = consumeExpression(scanner);
int exp2 = consumeExpression(scanner);
int exp3 = consumeExpression(scanner);
int exp4 = consumeExpression(scanner);
if( exp1 < 0 ) {
return exp2;
} else if( exp1 == 0 ) {
return exp3;
} ...
throw new RuntimeException("should not be here (TM)");
}