如何在没有回溯的情况下避免树梢上的左递归?

时间:2012-08-20 16:28:52

标签: ruby parsing treetop peg left-recursion

在我正在处理的这个简单的表达式解析器中,我无法避免左递归。本质上,我想将方程'f x y'解析为两个表达式'f x'和'(f x)y'(带隐式括号)。如何在避免左递归和回溯的同时做到这一点?是否必须有中间步骤?

#!/usr/bin/env ruby
require 'rubygems'
require 'treetop'
Treetop.load_from_string DATA.read

parser = ExpressionParser.new

p parser.parse('f x y').value

__END__
grammar Expression
   rule equation
      expression (w+ expression)*
   end
   rule expression
      expression w+ atom
   end
   rule atom
      var / '(' w* expression w* ')'
   end
   rule var
      [a-z]
   end
   rule w
      [\s\n\t\r]
   end
end

1 个答案:

答案 0 :(得分:1)

您没有提供有关所需结果的足够信息。特别是,你期望“f(a b)y”解析为“(f(a(b)))y”吗?我假设你做...这意味着一个没有开括号的函数有一个arity。

所以你想说:

rule equation
  expression w* var / expression w* parenthesised_list
end
rule parenthesised_list
  '(' w* ( expression w* )+ ')'
end

另一方面,如果你有f的arity的外部(语法)知识,并且你想要多次迭代“表达式” - 例如在解析TeX时发生 - 那么你将需要使用语义谓词& {| s | ...}在迭代表达式列表中)。请注意,传递给sempred块的参数不是SyntaxNode(由于此序列子规则尚未成功,因此尚未构造),而是序列中到目前为止累积的节点数组。块返回值的真实性决定了解析结果并可以停止迭代。

您可能考虑使用的另一个工具是先行(!stuff_I_dont_expect_to_follow或& stuff_that_must_follow)。

您也可以在http://groups.google.com/group/treetop-dev

中提出这些问题