【问题标题】:Checking for Operator precedence?检查运算符优先级?
【发布时间】:2023-04-07 02:31:02
【问题描述】:

所以我正在为一个项目制作一个解析器,它要求我做一个 if 语句来检查我当前的标记是否是左关联运算符,以及该标记是否比我的堆栈顶部具有更高的优先级。我不知道如何检查优先级。

该项目最终将成为一个计算器,它接收输入并将其转换为反向波兰符号。因此,在收到输入之前,代码不会知道要检查哪些运算符。

while(is<Operator>(infixTokens.at(i)){
  if(is<LAssocOperator>(infixTokens.at(i)) && infixTokens.at(i) >=tkn.top()){
  //exits while loop
  }
}

tkn 是一个堆栈,infixTokens 是一个向量。 >= 似乎不起作用。 检查每个元素中的哪个运算符大于另一个的最佳方法是什么?

【问题讨论】:

  • “似乎不起作用”不是一个有效的问题。除了您之外,没有人知道“tkn”是什么,也不知道您发布的小代码 sn-p 中引用的所有类和模板的定义,这对您的其余代码一无所知。
  • 我确实提到过 tkn 是一个堆栈。整个代码太大而无法放入。我需要知道的是,当我不知道要检查哪些运算符时,我到底如何检查哪个运算符的优先级高于另一个运算符。
  • 你显然需要知道所有的操作符是什么。然后你需要知道它们的相对优先级。一旦你有了这些信息,剩下的代码应该很明显了。
  • 如果你不知道会检查哪些算子,你建议看到后如何处理?分配应指定需要哪些运算符。如果没有,请返回并获得更严格的规格。你不想完成这项工作,去找客户要求付款,并被告知,“但我们也希望它做偏导。在我们有偏导支持之前,没有钱给你!”成功项目的第一步是制定一套明确且一致同意的要求。

标签: c++ operators token


【解决方案1】:

我能想到几个简单的方法。

最简单的是按优先级排序的运算符列表。如果 new 运算符在堆栈顶部的运算符之前,则 new 运算符具有更高的优先级。不会在这里花太多时间,因为它有致命的缺陷。这是有问题的,因为许多运算符具有相同的优先级(例如 + 和 -),并且必须按照找到它们的顺序执行。

第二个是运算符与其优先级之间的映射。例如:

struct Operator
{
    std::string op;
    int precedence;
}

在这种情况下,您可以比较 precedence 以查看哪个更大。

if (newoperator.precedence > stack.peek().precedence)
{
    // do something
}
else if (newoperator.precedence < stack.peek().precedence)
{
    // do something else
}
else
{ 
    // do whatever you do when the operators have the same precedence
}

因为这是 C++,所以你可以

struct Operator
{
    std::string op;
    int precedence;
    int prioritycompare(const Operator & other)
    {
        return precedence - other.precedence;
    }
}

让你的生活更轻松。

然后您可以更进一步,建立一个类层次结构,尽管在您的编程生涯的这一点上,您可能还不想去这里。相信我的话,写起来容易得多。

struct Operator
{
    std::string op;
    int precedence;
    ~Operator()
    {
        \\does nothing
    }
    virtual int operate(int A, int B) = 0; // pure virtual function
    int prioritycompare(const Operator & other)
    {
        return precedence - other.precedence;
    }
}

struct plus: public Operator
{  
    int operate(int A, int B)
    {
        return A+B;
    }
}

那么如果你手头有任何操作符,你可以测试优先级并执行操作

result = newoperator.operate(val1, val2);

并不关心它到底是哪种运算符,因为多态的魔力会为您处理簿记。程序将为正确的类调用正确的函数。

【讨论】:

  • 这对我当前的类层次结构造成了严重破坏。这些类型根本拒绝排队。没有更简单的方法吗?我觉得我的教授给我的“伪”代码似乎暗示了所以虽然没有告诉我如何......我觉得我在这里错过了一些东西
  • "最简单的是按优先级排序的运算符列表。如果新运算符在堆栈顶部的运算符之前,则新运算符具有更高的优先级。"最好的方法是什么?
猜你喜欢
  • 2011-07-07
  • 2019-11-12
  • 2011-06-21
  • 2013-02-24
  • 2012-08-10
  • 2020-03-05
  • 2012-12-13
相关资源
最近更新 更多