用函数解析表达式

时间:2019-01-26 22:29:17

标签: algorithm function parsing expression

这是我的情况:输入是一个字符串,其中包含诸如5+3*4之类的常规数学运算。也可以使用功能,即min(5,A*2)。此字符串已被标记化,现在我想使用堆栈(因此没有AST)解析它。我首先使用了Shunting Yard算法,但是这里出现了我的主要问题:

假设您具有以下(标记化的)字符串:min(1,2,3,+),这显然是无效的语法。但是,SYA会将其转换为输出堆栈1 2 3 + min(,希望您能看到问题的出现。从左到右进行解析时,它首先看到+,先计算2+3=5,然后再计算min(1,5),结果为1。因此,我的算法表示该表达式完全正确,而它应该引发语法错误(或类似的错误)。

预防这种情况的最佳方法是什么?添加特殊的定界符(例如逗号),使用其他算法还是什么?

1 个答案:

答案 0 :(得分:1)

为了防止出现此问题,您可能必须跟踪堆栈深度。我这样做的方式(我不确定这是“最佳”方式)是在另一个堆栈中。

新堆栈遵循以下规则:

  • 解析开括号,(或函数时,按0
    • 在嵌套函数的情况下执行此操作
  • 解析结束括号)时,将最后一项弹出,然后将其添加到堆栈中新的最后一个值中。
    • 刚弹出的数字是该函数返回的值。您可能希望它始终为1
  • 当解析逗号或类似的定界符时,从堆栈中弹出,将该数字添加到新的最后一个元素中,然后按0。
    • 重置,以便我们可以开始验证函数的下一个参数
    • 刚刚弹出的值是该语句返回了多少个值。您可能希望它始终为1
  • 将数字推入output时,增加此堆栈的顶部元素。
    • 这是output中可用的值。数字增加值的数量。二进制运算符必须至少具有2。
  • 将二进制运算符推到output时,递减顶部元素
    • 二进制运算符采用2个值并输出1,因此将输出上剩余的值总数减少了1。
    • 通常,接受 n 值并返回 m 值的 n 元运算符应添加( mn )到顶部元素。
    • 如果该值变为负,则抛出错误!

这将发现示例中的最后一个参数(仅包含一个+)会将堆栈的顶部减为-1,从而自动引发错误。

但是随后您可能会注意到,在示例3+中的最后一个参数将返回零,这不是负数。在这种情况下,您将在其中“您可能希望始终为1”的步骤之一中引发错误。