微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby – 树顶语法无限循环

我对于一种新的编程语言有了一些想法,所以我想我会尝试实现它.一位朋友建议我尝试使用Treetop( Ruby gem)来创建一个解析器. Treetop的文档稀少,我以前从未做过这样的事情.

我的解析器就像它有一个无限循环,但没有堆栈跟踪;事实证明难以追查.有人能指出我的入门级解析/ AST指南的方向吗?我真的需要一些列出规则,常用用法等东西来使用像Treetop这样的工具.我的解析器语法是在GitHub,以防有人希望帮助我改进它.

class {
  initialize = lambda (name) {
    receiver.name = name
  }

  greet = lambda {
    IO.puts("Hello,#{receiver.name}!")
  }
}.new(:World).greet()

解决方法

我让treetop将你的语言编译成.rb文件.这让我有所了解:

$tt -o /tmp/rip.rb /tmp/rip.treetop

然后我使用这个小存根重新创建循环:

require 'treetop'
load '/tmp/rip.rb'
RipParser.new.parse('')

这挂了.现在,不是那么有趣!空字符串可以再现您的问题中的十几行示例.

为了找出它挂起的位置,我使用Emacs键盘宏来编辑rip.rb,在每个方法的条目中添加一个调试语句.例如:

def _nt_root
  p [__LINE__,'_nt_root'] #DEBUG
  start_index = index

现在我们可以看到循环的范围:

[16,"root"]
[21,"_nt_root"]
[57,"_nt_statement"]
...
[3293,"_nt_eol"]
[3335,"_nt_semicolon"]
[3204,"_nt_comment"]
[57,"_nt_statement"]
[57,"_nt_statement"]
...

从那里进一步调试显示允许整数为空字符串:

rule integer
   digit*
end

这间接允许语句为空字符串,而顶级规则语句*永远使用空语句.更改*以修复循环,但显示一个问题:

/tmp/rip.rb:777:in `_nt_object': stack level too deep (SystemStackerror)
        from /tmp/rip.rb:757:in `_nt_compound_object'
        from /tmp/rip.rb:1726:in `_nt_range'
        from /tmp/rip.rb:1671:in `_nt_special_literals'
        from /tmp/rip.rb:825:in `_nt_literal_object'
        from /tmp/rip.rb:787:in `_nt_object'
        from /tmp/rip.rb:757:in `_nt_compound_object'
        from /tmp/rip.rb:1726:in `_nt_range'
        from /tmp/rip.rb:1671:in `_nt_special_literals'
         ... 3283 levels...

范围是间接的,通过special_literals,literal_object,object和compound_object进行左递归.树梢,当面对左递归时,吃掉堆叠直到它呕吐.我没有快速解决这个问题,但至少你有一个堆栈跟踪从现在开始.

此外,这不是您的直接问题,但数字的定义是奇数:它可以是一位数,也可以是多位数.这导致数字*或数字允许(可能)非法整数1________2.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐