简体   繁体   English

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

[英]Java - extending on a simple recursive descent parser

I've written this simple recursive parser method that evaluates simple arithmetic expressions (consisting of only +, -, *, and /). 我已经编写了这种简单的递归解析器方法,用于评估简单的算术表达式(仅由+,-,*和/组成)。

However, I am currently stuck on a few things: 但是,我目前停留在以下几件事上:

  1. How do I implement the recognition of parentheses? 如何实现括号的识别?
  2. How do I implement the recognition of unary operators? 如何实现对一元运算符的识别? eg unary minus (-) and factorial (!) 例如,一元减号(-)和阶乘(!)
  3. How do I implement the recognition of functions? 如何实现功能识别? eg sin(x) 例如sin(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); } 

Any help is appreciated. 任何帮助表示赞赏。 Thanks in advance! 提前致谢!

It looks like broad one but I'll try to put here my thought instead unreadable comment. 它看起来很宽泛,但我会尝试将我的想法写在这里,而不是不可读的评论。

  1. Looking for parantheses can be tricky because there are ones used for precedence and other for function arguments. 寻找括号可能很棘手,因为有一些用于优先级,而其他则用于函数参数。 What I'd do is to first look for '('. If it follows function, then skip it, otherwise go through all characters that follow until number of '(' == ')' and that would be what you pass to eval, everything before , between () and after ) would go to separate call to eval(). 我要做的是先寻找'('。如果它跟随函数,然后跳过它,否则遍历所有后续字符,直到'('==')'为止,这就是您传递给eval的内容,则()之间和之后的所有内容都将单独调用eval()。

  2. For unary operator '-' you'll most likely need to lookup previous character in you expression. 对于一元运算符“-”,您很可能需要在表达式中查找前一个字符。 Something like: 就像是:

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

These characters would absolutely be parantheses, other operators or if '-' had index 0. Just ask yourself how do you recognize unary operator and apply the same rules here. 这些字符绝对是括号,其他运算符,或者'-'的索引为0。只需问自己,您如何识别一元运算符并在此处应用相同的规则。

The same approach would be for '!': 同样的方法也适用于'!':

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

EDIT: As the OP correctly noticed, this approach would skip some expression parts so what's to be done for both functions and unary operators: 编辑:正如OP正确注意到的那样,这种方法会跳过某些表达式部分,因此对于函数和一元运算符都要做些什么:

return eval(everything before + eval(expression)+ everything after);
  1. Functions look exactly like unary operators, you only need to figure out precedence, so just put recognition of 'sin(' before looking for operators. Then apply the same approach as with unary operators. If you find function you remove the last closing parantheses. 函数看起来就像一元运算符,您只需要弄清楚优先级,因此只需在识别运算符之前先对'sin('进行识别即可。然后使用与一元运算符相同的方法。如果找到函数,则删除最后一个结束括号。

     return fun(eval(rest of expression)); 

Hope those thoughts help you a bit. 希望这些想法对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM