我已经根据维基百科中提到的内容在C++11中实现了调车场算法:
此实现不实现复合函数、具有可变参数数的函数、和一元运算符
while there are tokens to be read:
read a token.
if the token is a number, then:
push it to the output queue.
else if the token is a function then:
push it onto the operator stack
else if the token is an operator then:
while ((there is a operator at the top of the operator stack)
and ((the operator at the top of the operator stack has greater precedence)
or (the operator at the top of the operator stack has equal precedence and the token is left associative))
and (the operator at the top of the operator stack is not a left parenthesis)):
pop operators from the operator stack onto the output queue.
push it onto the operator stack.
else if the token is a left parenthesis (i.e. "("), then:
push it onto the operator stack.
else if the token is a right parenthesis (i.e. ")"), then:
while the operator at the top of the operator stack is not a left parenthesis:
pop the operator from the operator stack onto the output queue.
/* If the stack runs out without finding a left parenthesis, then there are mismatched parentheses. */
if there is a left parenthesis at the top of the operator stack, then:
pop the operator from the operator stack and discard it
/* After while loop, if operator stack not null, pop everything to output queue */
if there are no more tokens to read then:
while there are still operator tokens on the stack:
/* If the operator token on the top of the stack is a parenthesis, then there are mismatched parentheses. */
pop the operator from the operator stack onto the output queue.
exit.
正如你所看到的,有人提到这个算法不处理一元算子,假设我有一个比所有其他算子都强的!
,如果有,我应该对我的算法做什么改变?
一些法律使用!
运算符的示例:
!1
! 1
! (1)
!( 1 + 2)
再加上一个小问题,这个算法能处理像1==2
这样的错误语法吗?
问题1:
为了使您的算法工作,您应该在中缀运算符之前解析前缀操作符 混合修复运算符问题2: 这里的解析器不处理像 编辑1: ";调整">(部分解决了这个问题(:将运算符视为右关联运算符,并使其优先级高于其他运算符。 编辑2: 这(正如@dure在评论中指出的那样(只是一个调整,因为il将导致解析器解析前缀和后缀运算符而不加区分,并且需要进一步小心以避免错误。!
,只需将其视为一个开括号(
(然后您需要调整堆栈虚拟机以允许这种运算符(。我建议将if检查移到中缀运算符之前的括号(变化不大,但可读性更强(。我还要说的是,如果你想同时实现运算符优先级、后缀运算符和1 == 2
这样的操作,它只解析它们。基于堆栈的虚拟机处理它们,1 == 2
是一个完全好的比较,因为它应该返回false
。如果您计划使用布尔表达式和算术表达式,则会出现这种情况。