我正在尝试使用 JavaCC 构建一个可以处理各种表达式的简单命令行计算器。虽然有很多关于如何编写语法的教程,但到目前为止我所看到的都没有解释之后会发生什么。
我现在理解的是,一个字符串传入解析器后,会被拆分成一个tokens,变成一个解析树。接下来发生什么?我是否遍历解析树,对每个节点的内容进行一堆 if-else 字符串比较,然后执行适当的功能?
我正在尝试使用 JavaCC 构建一个可以处理各种表达式的简单命令行计算器。虽然有很多关于如何编写语法的教程,但到目前为止我所看到的都没有解释之后会发生什么。
我现在理解的是,一个字符串传入解析器后,会被拆分成一个tokens,变成一个解析树。接下来发生什么?我是否遍历解析树,对每个节点的内容进行一堆 if-else 字符串比较,然后执行适当的功能?
我强烈建议您观看Scott Stanchfield 的 ANTLR 3.x 教程。即使您最终没有使用 ANTLR,这对您的项目来说可能有点过头了,但我对此表示怀疑,通过观察他的思考过程,您会学到很多东西。
一般来说,这个过程是...
您需要根据需要实际编译或解释它..
对于计算器,您只需要递归地访问树并评估解析的树,而使用更复杂的语言,您必须将其翻译成类似于汇编但保持与底层架构抽象的中间语言。
当然,您可以开发自己的简单虚拟机,该虚拟机能够执行一组指令,您的语言在其中编译,但在您的情况下这将是矫枉过正......只需访问解析树。就像是:
enum Operation {
PLUS, MINUS
}
interface TreeNode {
float eval();
}
class TreeFloat implements TreeNode {
float val;
float eval() { return val; }
}
class TreeBinaryOp implements TreeNode {
TreeNode first;
TreeNode second;
Operation op;
float eval() {
if (op == PLUS)
return first.eval()+second.eval();
}
然后你只需在树的根部调用 eval 函数。可能需要进行语义检查(如果您计划使用变量或其他内容,还需要构建符号表)。
一些解析器生成器(例如 YACC)允许您将操作放入语法中,因此当您应用某个产生式时,您还可以在该产生式期间应用定义的操作。
例如在 YACC:
E: NUM + NUM {$$ = $1.value + $2.value};
将添加 NUM 的值并将结果返回给 E 非终端。
不确定 JavaCC 允许您做什么。
我是否遍历解析树,对每个节点的内容进行一堆 if-else 字符串比较,然后执行适当的功能?
不,不需要构建解析树来实现计算器。在您将创建新节点对象的代码部分中,只需进行计算并返回一个数字。
JavaCC 允许您为产品选择任何返回类型,因此只需提供您的返回编号即可。