Java - 扩展简单的递归下降解析器

标签 java parsing recursion

我编写了这个简单的递归解析器方法,用于计算简单的算术表达式(仅包含 +、-、* 和/)。

但是,我目前陷入了一些困境:

  1. 如何实现括号识别?
  2. 如何实现一元运算符的识别?例如一元减号 (-) 和阶乘 (!)
  3. 如何实现函数的识别?例如正弦(x)

    private static double eval(String s) {
    
        if (s.charAt(0) == '-' || s.charAt(0) == '+') {
            s = "0" + s;
        }
    
        if (s.indexOf("+") > -1) {
            return (eval(s.substring(0, s.indexOf("+"))) + eval(s.substring(s.indexOf("+") + 1, s.length())));
        } else if (s.indexOf("-") > -1) {
            return (eval(s.substring(0, s.indexOf("-"))) - eval(s.substring(s.indexOf("-") + 1, s.length())));
        } else if (s.indexOf("*") > -1) {
            return (eval(s.substring(0, s.indexOf("*"))) * eval(s.substring(s.indexOf("*") + 1, s.length())));
        } else if (s.indexOf("/") > -1) {
            return (eval(s.substring(0, s.indexOf("/"))) / eval(s.substring(s.indexOf("/") + 1, s.length())));
        } else if (s.indexOf("^") > -1) {
            return (Math.pow(evaluate(s.substring(0, s.indexOf("^"))), evaluate(s.substring(s.indexOf("^") + 1, s.length()))));
        }
    
        return Double.parseDouble(s);
    }
    

感谢任何帮助。提前致谢!

最佳答案

它看起来很宽泛,但我会尝试在这里写下我的想法,而不是难以理解的评论。

  1. 查找括号可能很棘手,因为有些括号用于优先级,有些用于函数参数。我要做的就是首先查找 '('。如果它跟随 function,则跳过它,否则遍历后面的所有字符,直到 '(' == ')' 的数量,这将是您传递给 eval 的内容, () 之前、 () 和 ) 之后的所有内容都将单独调用 eval()。

  2. 对于一元运算符“-”,您很可能需要查找表达式中的前一个字符。像这样的东西:

    } else if (s.indexOf("-") > -1) { // keeping this index would make more sense now
       if char at index -1 from '-' in list of characters indicating unary operator
          return -eval(s.substring(s.indexOf("-")+1, s.length())));
    
    else {
    return (eval(s.substring(0, s.indexOf("-"))) - 
      eval(s.substring(s.indexOf("-") + 1, s.length())));
        }
    }
    

这些字符绝对是括号、其他运算符或者“-”的索引为 0。只需问问自己如何识别一元运算符并在此处应用相同的规则。

同样的方法也适用于“!”:

if(s.indexOf("!") > -1) {
    return fact(eval(s.substring(s.indexOf("-") + 1, s.length())));
}

编辑: 正如OP正确注意到的那样,这种方法会跳过一些表达式部分,所以对函数和一元运算符要做什么:

return eval(everything before + eval(expression)+ everything after);
  • 函数看起来与一元运算符完全相同,您只需要弄清楚优先级,因此只需在查找运算符之前识别“sin(”即可。然后应用与一元运算符相同的方法。 如果找到函数,则删除最后一个右括号。

    return fun(eval(rest of expression));
    
  • 希望这些想法对您有所帮助。

    关于Java - 扩展简单的递归下降解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30884616/

    相关文章:

    recursion - Dyalog APL - 汉诺塔 - 无法正常循环

    Java boolean 算法检查位数是否为偶数

    Python递归序列相关代码

    java - 如何设置系统默认字体为JComboBox<String>的选中项?

    java - 正则表达式查看小写字母是否存在

    java - 无法使用 TIKA 提取文本

    bash - 从 Bash 中的配置文件解析变量

    java - 收集器与结果类型中的通配符不匹配

    java - 为什么我的线程没有启动?

    java - XML 解析到 MySQL 数据库