考虑一个包含运算符、函数和操作数的表达式,例如:
2 + sin ( max ( 2, 3 ) / 3 * 3.1415 )
如何通过编程验证表达式,使得任何函数都必须有正确数量的参数?例如abs、sin、cos必须恰好有1个参数,而sum、avg、max、min必须有2个或更多。考虑到每个参数本身可能是非常复杂的表达式,因此在程序上确定这一点似乎并不容易。我已经编写了一个词法分析器(lexer),并成功将表达式转换为后缀/RPN形式(即:2 3 max 3 / 3.1415 * sin 2 +)。但我仍然没有找到解决方案。我希望能得到一些代码或伪代码,以指导我从头开始编写。最好使用Java。以下是我的词法分析器代码:
public static List<Token> shunt(List<Token> tokens) throws Exception {
List<Token> rpn = new ArrayList<Token>();
Iterator<Token> it = tokens.iterator();
Stack<Token> stack = new Stack<Token>();
while (it.hasNext()) {
Token token = it.next();
if (Type.NUMBER.equals(token.type))
rpn.add(token);
if (Type.FUNCTION.equals(token.type) || Type.LPAREN.equals(token.type))
stack.push(token);
if (Type.COMMA.equals(token.type)) {
while (!stack.isEmpty() && !Type.LPAREN.equals(stack.peek().type))
rpn.add(stack.pop());
if (stack.isEmpty())
throw new Exception("Missing left parenthesis!");
}
if (Type.OPERATOR.equals(token.type)) {
while (!stack.isEmpty() && Type.OPERATOR.equals(stack.peek().type))
rpn.add(stack.pop());
stack.add(token);
}
if (Type.RPAREN.equals(token.type)) {
while (!stack.isEmpty() && !Type.LPAREN.equals(stack.peek().type))
rpn.add(stack.pop());
if (stack.isEmpty())
throw new Exception("Missing left parenthesis!");
stack.pop();
if (!stack.isEmpty() && Type.FUNCTION.equals(stack.peek().type))
rpn.add(stack.pop());
}
}
while (!stack.isEmpty()) {
if (Type.LPAREN.equals(stack.peek().type) || Type.RPAREN.equals(stack.peek().type))
throw new Exception("Mismatched parenthesis!");
rpn.add(stack.pop());
}
return rpn;
}