Lpeg"规则中的空循环"错误

时间:2016-06-18 03:59:36

标签: lua lpeg

任何人都可以提供明确的解释和一些显示此错误的简单示例,显然与匹配时间捕获(Cmt)有关吗?

我不明白我能找到的唯一提及,即

http://lua-users.org/lists/lua-l/2013-06/msg00086.html

由于

1 个答案:

答案 0 :(得分:3)

所以这个问题有点陈旧,但它是最早的搜索结果之一。互联网上关于这一点并不是很多,而且可能不是很明显的错误。

错误消息有点误导,但正在发生的事情 - 在正式的PEG术语中,至少我理解它们 - 有一个重复运算符应用于解析表达式,它不会消耗任何输入。

或者换句话说,LPeg检测到一个可以匹配空字符串的循环,该循环永远不会完成。有一个名为LuLPeg的纯Lua实现,它没有这个特殊的检查,如果你执行你的语法,它很容易进入无限循环。

我正在修补一点玩具BASIC-ish语言,并遇到以上问题:

grammar = P{ "input",
  input = V"block"^0 * -1,
  block = V"expression"^0,
  -- (define expression here)
}

根据这个想法,根输入是一个可选的代码块,而一个块是零个或多个表达式。这很简单,当然,我正在遗漏空白处理等等。但是当你调用语法时会发生什么:匹配(“”)?

  1. 剩余字符串:“”,输入时。看它是否匹配一个块。
  2. 剩余字符串:“”,块。看看它是否与表达式匹配。
  3. 剩下的字符串:“”,表达式。为了时间,让我们说它不匹配
  4. 剩余字符串:“”,块。规则以零表达式结束,不消耗任何输入。
  5. 剩余字符串:“”,输入时。消耗一个块,检查是否有更多块匹配。
  6. 剩余字符串:“”,块。看看它是否与表达式匹配。
  7. 等等。由于V“block”匹配空字符串,因此输入可以找到无限数量的块以满足规则V“block”^ 0。在这种情况下,有两个很好的解决方案:将输入设置为最多一个块,或者将块设置为至少一个表达式,并且可以将块设置为^ 0。所以:

    grammar = P{ "input", -- blocks can be empty, input contains one (empty or otherwise) block
      input = V"block" * -1,
      block = V"expression"^0,
      -- (define expression here)
    }
    

    或者:

    grammar = P{ "input", -- blocks must be at least one expression, root can have one
      input = V"block"^0 * -1,
      block = V"expression"^1,
      -- (define expression here)
    }
    

    在第一种情况下,空字符串将匹配一个块,该块满足输入规则。在第二个中,空字符串将失败阻塞,实现具有零匹配块的输入规则。

    我还不需要使用Cmt,但我相信发生的事情是旧版本的LPeg假设该功能会失败或消耗输入,即使Cmt调用中的规则可能匹配空字符串。更新的版本没有这个假设。