【问题标题】:Trying to understand parsers试图理解解析器
【发布时间】:2023-04-04 08:39:01
【问题描述】:

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

我现在理解的是,一个字符串传入解析器后,会被拆分成一个token,变成一个解析树。接下来发生什么?我是否遍历解析树,对每个节点的内容进行一堆 if-else 字符串比较,然后执行相应的功能?

【问题讨论】:

标签: java parser-generator javacc


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    你需要根据你的需要实际编译或解释它..

    对于计算器,您只需要递归地访问树并评估解析的树,而使用更复杂的语言,您必须将其翻译成类似于汇编但保持与底层架构抽象的中间语言。

    当然,您可以开发自己的简单虚拟机,该虚拟机能够执行一组指令,您的语言可以在其中编译,但在您的情况下这将是多余的......只需访问解析树即可。比如:

    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 函数。可能需要进行语义检查(如果您打算使用变量或其他任何东西,还需要构建符号表)。

    【讨论】:

      【解决方案3】:

      我是不是遍历解析树,对每个节点的内容做一堆 if-else 字符串比较,然后执行相应的功能?

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

      JavaCC 允许您为产品选择任何返回类型,因此只需提供您的返回编号即可。

      【讨论】:

        【解决方案4】:

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

        例如在 YACC:

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

        将添加 NUM 的值并将结果返回给 E 非终结符。

        不确定 JavaCC 可以让您做什么。

        【讨论】:

          猜你喜欢
          • 2018-11-17
          • 1970-01-01
          • 1970-01-01
          • 2011-03-17
          • 1970-01-01
          • 1970-01-01
          • 2020-08-30
          • 2021-05-30
          • 1970-01-01
          相关资源
          最近更新 更多