2

明確な説明と、このエラーを示す簡単な例を誰かが提供できますか?明らかに match-time capture (Cmt) に関連していますか?

私が見つけることができる唯一の言及を理解していません。

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

ありがとう

4

1 に答える 1

4

この質問は少し古いですが、最初の検索結果の 1 つです。これについてインターネット上にはあまり情報がありません。

エラー メッセージは少し誤解を招きますが、何が起こっているのか (少なくとも私が理解している限り、正式な PEG 用語では)、入力を消費できない解析式に繰り返し演算子が適用されています。

つまり、LPeg は空の文字列に一致するループを検出しましたが、これは決して完了しません。この特定のチェックが欠けている LuLPeg と呼ばれる純粋な Lua 実装があり、文法を実行すると簡単に無限ループに入る可能性があります。

私は小さなおもちゃのBASICっぽい言語をいじっていますが、上記の問題は次のとおりです。

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

ルート入力はオプションのコード ブロックであり、ブロックは 0 個以上の式であるという考えに基づいています。これはかなり単純化されています。もちろん、空白の処理などは省いています。しかし、grammar:match("") を呼び出すとどうなるでしょうか?

  1. 残りの文字列: ""、入力時。ブロックに一致するかどうかを確認します。
  2. 残りの文字列: ""、ブロックで。式に一致するかどうかを確認します。
  3. 残りの文字列: ""、式で。時間のために、一致しないとしましょう
  4. 残りの文字列: ""、ブロックで。ルールはゼロ式で終了し、入力は消費されません。
  5. 残りの文字列: ""、入力時。1 つのブロックが消費されました。さらに多くのブロックが一致するかどうかを確認します。
  6. 残りの文字列: ""、ブロックで。式に一致するかどうかを確認します。

等々。V"block" は空の文字列に一致するため、入力は規則 V"block"^0 を満たすブロックを無限に見つけることができます。この場合、適切な解決策が 2 つあります。入力を最大で 1 つのブロックに設定するか、ブロックが少なくとも 1 つの式である必要があり、ブロックが存在する可能性がある場合は常に ^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)
}

最初のケースでは、空の文字列は入力ルールを満たすブロックに一致します。2 番目の例では、空の文字列はブロックに失敗し、一致するブロックがゼロの入力ルールを満たします。

私はまだ Cmt を使う必要はありませんでしたが、古いバージョンの LPeg では、Cmt 呼び出し内のルールが空の文字列に一致する可能性がある場合でも、関数が失敗するか、入力を消費すると想定していたと思います。最近のリリースには、この前提がありません。

于 2016-11-13T04:16:12.923 に答える