【问题标题】:Parse expression with functions用函数解析表达式
【发布时间】:2019-01-26 22:29:17
【问题描述】:

这是我的情况:输入是一个字符串,其中包含一个普通的数学运算,例如5+3*4。函数也是可能的,即min(5,A*2)。这个字符串已经被标记化了,现在我想使用堆栈来解析它(所以没有 AST)。我首先使用了调车场算法,但这里出现了我的主要问题:

假设你有这个(标记化的)字符串:min(1,2,3,+),这显然是无效的语法。但是,SYA 将其转换为输出堆栈1 2 3 + min(,希望您能看到问题的出现。从左到右解析时,它首先看到+,计算2+3=5,然后计算min(1,5),结果为1。因此,我的算法说这个表达式完全没问题,但它应该抛出一个语法错误(或类似的东西)。

防止此类事情发生的最佳方法是什么?添加一个特殊的分隔符(例如逗号),使用不同的算法,还是什么?

【问题讨论】:

  • Shunting-Yard 解析器的伪代码可以理解this answer 中的函数调用。请注意,当伪代码告诉您“将( 标记为后缀运算符”时,这意味着您需要将其视为函数调用。

标签: algorithm function parsing expression


【解决方案1】:

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

新堆栈遵循以下规则:

  • 当解析开括号、( 或函数时,推送0
    • 在嵌套函数的情况下执行此操作
  • 当解析右括号) 时,弹出最后一项并将其添加到堆栈上新的最后一个值。
    • 刚刚弹出的数字是函数返回的值的数量。您可能希望它始终是 1
  • 解析逗号或类似分隔符时,从堆栈中弹出,将该数字添加到新的最后一个元素,然后压入 0。
    • 重置以便我们可以开始验证函数的下一个参数
    • 刚刚弹出的值是语句返回的值的数量。您可能希望它始终是 1
  • 当一个数字被压入output 时,增加这个堆栈的顶部元素。
    • 这是output 中可用的值的数量。数字会增加值的数量。二元运算符至少需要 2 个。
  • 当二元运算符被推送到output 时,递减顶部元素
    • 二元运算符接受 2 个值并输出 1,从而将输出中剩余的值的总数减少 1。
    • 一般来说,一个 n-ary 运算符接受 n 个值并返回 m 个值应该添加 (m-n) 到顶部元素。
    • 如果此值变为负数,则抛出错误!

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    相关资源
    最近更新 更多