关于分流场算法的问题

Questions about Shunting-yard algorithm

本文关键字:算法 问题 分流 于分流      更新时间:2023-10-16

我已经按照分流场算法在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"。

函数应该被视为运算符,并且比所有传统运算符具有更高的优先级,对吗?

我的理解是,operator代币和function代币之间不应该混淆。在格式良好的expression中,每个函数的参数必须括在左括号和右括号之间。而其他任何地方的括号用于强加优先级或只是为了清楚起见。基于这一观察,您的问题的答案

函数应该被视为运算符,并且比所有传统运算符具有更高的优先级,对吗?

是否。

当在算法的描述中operator说时,它意味着operator,当它说function时,它意味着function 。对于格式良好的expression,只有阅读右括号会导致您弹出右括号关闭参数列表的functionfunctionoperator 之间的任何混淆都会误导您的实现,从而对错误的表达式进行解释。想象一下以下表达式

4 + (sin 3 + 1)

如果您将function视为运算符,您将对此有所了解,而括号可能只是放错了位置。你也会对此有所了解

4 - sin() 5*6

当您考虑具有多个参数的函数时,它会变得更加微妙。

它说"虽然有一个运算符令牌o2

",而我的意思是"当有一个运算符或函数令牌o2时"。

函数应该被视为运算符,并且比所有传统运算符具有更高的优先级,对吗?

文本是正确的。 如果运算符堆栈上有函数符号,则意味着您当前正在解析函数参数,并且在将函数符号移动到输出队列之前,它们都已转到输出队列。

如果输入的前面有一个运算符,在

运算符堆栈的顶部有一个函数符号,则意味着您缺少左括号。

在某些情况下,你可以侥幸逃脱,就像sin a + b根据上述算法将输出a b + sin,这与sin(a+b)的输出相同:在这两种情况下(在堆栈顶部都有sin,或者在堆栈顶部有((,你不会在上面的循环中输入它, 但是+推到堆栈上。