算子优先算法

时间:2014-11-05 23:25:04

标签: java algorithm compiler-construction evaluation operator-precedence

我目前正在编写自定义编程语言的编译器。编译器转换每个单个运算符或调用

形式的对象
Call : Value
{
  Value instance
  String name
  Value[] arguments
}

例如,表达式3 + 4(= 3.+(4))变为

Call : Value
{
  instance = Value(3)
  name = "+"
  arguments = [ Value(4) ]
}

表达式3 + 4 * 5将由解析器评估为3.+(4).*(5)

Call : Value
{
  instance = Call
             {
               instance = Value(3)
               name = "+"
               arguments = Value(4)
             }
  name = "*"
  arguments = [ Value(5) ]
}

我知道有一个函数可以在这个结构中创建一个调用列表,并按运算符优先级对它们进行排序,结果如下所示:

[ 3.+(4).*(5), 3.+(4) ](以上表格)

我现在需要的是一种算法,对它们进行排序,使第一个表达式为3.+(4.*(5))。这个问题是上面的结果可以有任何长度。我当前的实现(依赖于它是2个或更少的中缀运算符)是这样的:

(go through all elements)
{
  current.arguments = [ prev ]
  prev.instance = current.arguments[0]
}

我知道运算符优先级通常使用BNF文件中的特殊结构来实现解析器生成,但由于我使用的是自定义解析器,它总是从左到右评估,我不能使用这样的解决方案。

1 个答案:

答案 0 :(得分:4)

一个常见的解决方案是一种算法,有时称为" shunting yard",它使用操作员堆栈。

  • 以最低优先级在堆栈上推送标记
  • 获得主要
  • 获得运营商
  • 如果优先级较低或不再有运算符,则弹出堆栈并生成代码
  • 将操作员推入堆栈
  • 循环直到标记完全剩下

我确定你会找到更好的解释,但这就是我的做法。