ruby - 如何消除 Verilog 语法示例中的左递归

标签 ruby treetop

我正在使用 Treetop 为 Verilog 语言创建语法,并且遇到过一些情况,其中语言规范涉及无法转换为 Treetop 的左递归结构。

我已经阅读了一些这方面的资料,这个答案很好地总结了消除左递归的通用方法:Left recursion elimination

但是,我无法完全理解这实际上是如何工作的,如果更有知识的人可以确认我在这里的方法是否正确,我将不胜感激......

对于这个包含左递归的原始规则(注释是它在语言规范中的写法):

  # constant_expression ::=
  #   constant_primary
  #   | unary_operator { attribute_instance } constant_primary
  #   | constant_expression binary_operator { attribute_instance } constant_expression
  #   | constant_expression ? { attribute_instance } constant_expression : constant_expression
  rule constant_expression
    constant_primary /
    (unary_operator (s attribute_instance)* s constant_primary) /
    (constant_expression s binary_operator (s attribute_instance)* s constant_expression) /
    (constant_expression s "?" (s attribute_instance)* s constant_expression s ":" s constant_expression)
  end 

以下是否真的等同于删除了左递归?

  rule constant_expression
    (constant_primary constant_expression_tail?) /
    (unary_operator (s attribute_instance)* s constant_primary constant_expression_tail?)
  end

  rule constant_expression_tail
    (s binary_operator (s attribute_instance)* s constant_expression constant_expression_tail?) /
    (s "?" (s attribute_instance)* s constant_expression s ":" s constant_expression constant_expression_tail?)
  end 

最佳答案

这似乎有道理并且同样的事情。可能有助于理解的一件事是像下面的代码一样重写。关于 PEG 语法要记住的一件事是,如果规则无法匹配,它将尝试匹配下一个交替。

rule constant_expression
   (constant_primary / (unary_operator (s attribute_instance)* s constant_primary)) constant_expression_tail?
end

rule constant_expression_tail
   ((s binary_operator (s attribute_instance)* s) /
    (s "?" (s attribute_instance)* s constant_expression s ":" s)) constant_expression constant_expression_tail?
end

关于ruby - 如何消除 Verilog 语法示例中的左递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47163764/

相关文章:

iphone - 设计和 Rails 3 中的 http 身份验证

ruby - 如何处理树顶左递归

ruby - Visual Studio 代码 : Disabling Error/Warning checks in for specific file type

ruby - 树顶 bool 逻辑运算

ruby-on-rails - 将文件 MIME 类型转换为人类可读的名称

c - ruby 1.9.2 中的 rfuzz 编译错误

Ruby 可重复使用的 map block

ruby - Treetop 语法中的匹配标签对

ruby - 树顶解析器 : Function definition syntax - n arguments

ruby-on-rails - Ruby:如何测试私有(private)方法?