我对于一种新的编程语言有了一些想法,所以我想我会尝试实现它.一位朋友建议我尝试使用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 举报,一经查实,本站将立刻删除。