试图理解解析器

时间:2011-04-06 01:31:48

标签: java parser-generator javacc

我正在尝试使用JavaCC构建一个可以处理各种表达式的简单命令行计算器。虽然有很多关于如何编写语法的教程,但到目前为止我所看到的并没有解释之后会发生什么。

我现在理解的是,在将一个字符串传递给解析器之后,它会被拆分为一个标记并变成一个解析树。接下来发生什么?我是否遍历解析树,对每个节点的内容进行一堆if-else字符串比较,然后执行相应的函数?

4 个答案:

答案 0 :(得分:2)

我强烈建议你观看Scott Stanchfield's ANTLR 3.x tutorials。即使你最终没有使用ANTLR,这可能对你的项目来说太过分了,但我对此表示怀疑,你会通过观察他的思考过程来学到很多东西。

一般来说,这个过程是......

  1. 构建词法分析器以了解您的令牌
  2. 构建一个解析器,可以验证和理解并将输入组织成一个抽象语法树(AST),它应该代表一个简化/易于使用的语法版本
  3. 根据AST
  4. 运行任何计算

答案 1 :(得分:0)

您需要根据需要实际编译或解释它。

对于计算器,您只需递归访问树并评估解析后的树,而使用更复杂的语言,您必须将其转换为类似汇编的中间语言,但保留对底层架构的抽象。

当然你可以开发自己的简单虚拟机,它能够执行一组你的语言编译的指令,但在你的情况下它会有点过分。只需访问解析树。类似的东西:

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函数。可能需要进行语义检查(如果您计划使用变量或其他任何内容,也可以构建符号表。)

答案 2 :(得分:0)

  

我是否遍历解析树,对每个节点的内容进行一系列if-else字符串比较,然后执行相应的函数?

不,没有必要构建一个解析树来实现计算器。在您要创建新节点对象的代码部分中,只需执行计算并返回一个数字。

JavaCC允许您为制作选择任何返回类型,因此只需要输入您的返回数字。

答案 3 :(得分:0)

某些解析器生成器(例如YACC)允许您将操作放在语法中,因此在应用某个生成时,您还可以在生成期间应用已定义的操作。

E.g。在YACC:

E: NUM + NUM     {$$ = $1.value + $2.value};

将添加NUM的值并将结果返回到E非终端。

不确定JavaCC允许您做什么。