Java—在简单递归下降解析器上的扩展

Java—在简单递归下降解析器上的扩展,java,parsing,recursion,Java,Parsing,Recursion,我编写了这个简单的递归解析器方法,它计算简单的算术表达式(只包含+、-、*、和/) 然而,我目前在一些事情上陷入困境: 如何实现括号的识别 如何实现一元运算符的识别?e、 g.一元负(-)和阶乘(!) 如何实现功能识别?e、 g.单(x) 感谢您的帮助。提前谢谢 它看起来很宽泛,但我会尽量把我的想法放在这里,而不是不可读的评论 寻找偏执论点可能很棘手,因为有些偏执论点用于优先级,有些偏执论点用于函数参数。我要做的是首先查找“(”。如果它跟在函数后面,那么跳过它,否则遍历所有跟在后面的字符,直到

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

然而,我目前在一些事情上陷入困境:

  • 如何实现括号的识别
  • 如何实现一元运算符的识别?e、 g.一元负(-)和阶乘(!)
  • 如何实现功能识别?e、 g.单(x)


  • 感谢您的帮助。提前谢谢

    它看起来很宽泛,但我会尽量把我的想法放在这里,而不是不可读的评论

  • 寻找偏执论点可能很棘手,因为有些偏执论点用于优先级,有些偏执论点用于函数参数。我要做的是首先查找“(”。如果它跟在函数后面,那么跳过它,否则遍历所有跟在后面的字符,直到“(“==”)的数量,这就是传递给eval的内容,之前、之间()和之后的所有内容都将转到对eval()的单独调用

  • 对于一元运算符“-”,您很可能需要查找表达式中的上一个字符。比如:

    } 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));
    

  • 希望这些想法能对你有所帮助。

    看起来很宽泛,但我会尽量把我的想法放在这里,而不是不可读的评论

  • 寻找偏执是很棘手的,因为有些偏执用于优先级,有些用于函数参数。我要做的是首先查找“(”。如果它跟在函数后面,那么跳过它,否则遍历所有跟在后面的字符,直到“(“=”)的数目,这就是传递给eval的内容,之前的所有内容,在()和之后)将转到对eval()的单独调用

  • 对于一元运算符“-”,您很可能需要查找表达式中的前一个字符。类似于:

    } 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())));
        }
    }
    
  • 这些字符绝对是parantesses、其他运算符,或者如果“-”的索引为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));
    


  • 希望这些想法能对你有所帮助。

    你听说过反向波兰语符号吗?或者它必须是递归的?是的,我用堆栈做了一个数学解析器(使用分流码从中缀转换为后缀).这个必须是递归的:/你听说过反向波兰符号吗?或者它必须是递归的?是的,我用堆栈做了一个数学解析器(使用分流码从中缀转换为后缀).这个必须是递归的:/你听说过反向波兰符号吗?或者它必须是递归的?是的,我用堆栈做了一个数学解析器(使用分流码从中缀转换为后缀).这个必须是递归的:/I我不太明白一元负号的逻辑是如何工作的-它说
    return-eval(s.substring(s.indexOf(“-”)+1,s.length())
    ?它的意思是对“-”右边的表达式求值,并将符号改为“-”。当我想到它时,对于递归来说,替换对一元运算符的调用,然后对表达式求值会更有意义。请参见编辑的pts2&3。但是,这样会不会忽略“-”左边的内容?
    返回eval(在+eval(表达式)之前的所有内容)+(后面的所有内容);
    在一元'-'上拆分字符串。前面的内容在这里作为字符串。作为'-'参数的表达式将是:1)函数或2)数字。覆盖这两个案例,剩下的是表达式后面的内容。括号中的表达式将在前面介绍,所以您已经有了-for number。让它递归工作并不是那么简单,这就是我建议使用堆叠方法的原因。我不太明白一元负号的逻辑是如何工作的——它说
    return-eval(s.substring(s.indexOf(“-”)+1,s.length())?它表示对“-”右侧的表达式求值,并将符号更改为“-”。当我想到它时,对于递归来说,替换对一元运算符的调用,然后对表达式求值会更有意义。参见已编辑的pts2&3。那么,会不会忽略“-”左侧的内容?
    返回eval(eval之前的所有内容+eval(表达式)+之后的所有内容)拆分一元'-'上的字符串。前面的内容以字符串的形式出现在这里。作为“-”参数的表达式将是:1)函数或2)数字。覆盖这两个案例,剩下的是表达式后面的内容。括号中的表达式将在前面介绍,所以您已经有了-for number。让它递归工作并不是那么简单,这就是我建议使用堆叠方法的原因。我不太明白一元负号的逻辑是如何工作的——它说
    return-eval(s.substring(s.indexOf(“-”)+1,s.length())?它表示对“-”右侧的表达式求值,并将符号更改为“-”。当我想到它时,对于递归来说,替换对一元运算符和t的调用更有意义