我在Shunting-yard algorithm之后用C ++实现了一个表达式解析器,但是对维基百科的解释有问题。它位于'详细算法'部分:
If the token is an operator, o1, then: while there is an operator token o2, at the top of the operator stack and either o1 is left-associative and its precedence is less than or equal to that of o2, or o1 is right associative, and has precedence less than that of o2, pop o2 off the operator stack, onto the output queue; at the end of iteration push o1 onto the operator stack.
它说“while there is an operator token o2
”,我的不确定是“while there is an operator or function token o2
”。
函数应该被视为运算符,并且具有比所有传统运算符更高的优先级,是吗?
答案 0 :(得分:1)
我的理解是,operator
令牌和function
令牌之间不应存在混淆。在格式良好的expression
中,每个函数的参数必须包含在左括号和右括号之间。虽然其他任何地方的括号用于强加优先权或仅仅为了清楚。
根据这一观察,您的问题的答案
函数应该被视为运算符,并且具有比所有传统运算符更高的优先级,是吗?
是否。
如果在算法说明中说operator
,则表示operator
,而当表示function
时,表示function
。对于格式良好的expression
,只有右括号的读取才会弹出右括号关闭参数列表的function
。 function
和operator
之间的任何混淆都会误导您的实现,以便对错误的表达式进行解释。想象一下以下表达式
4 + (sin 3 + 1)
如果你像操作员一样对待function
,那么你就会明白这一点,而括号可能只是错位了。你也会对这个
4 - sin() 5*6
当你考虑具有多个参数的函数时,它会变得更加微妙。
答案 1 :(得分:0)
它说“虽然有一个操作员令牌o2”,但我的不确定是“当有一个操作员或功能令牌o2”时。
函数应该被视为运算符,并且具有比所有传统运算符更高的优先级,是吗?
文字是正确的。如果在操作符堆栈上有一个函数符号,则表示您当前正在解析函数参数,并且在将函数符号移动到那里之前它们都已进入输出队列。
如果输入前面有一个操作符,操作符堆栈顶部有一个功能符号,则表示您缺少左括号。
在某些情况下,你可以像sin a + b
一样豁免它,根据上面的算法将输出a b + sin
,这与sin(a+b)
的输出相同:在两种情况下(具有在堆栈顶部sin
,或在堆栈顶部有(
),您不要在上面输入while循环,而是在堆栈上推送+
。