3

パスカルの文法によれば、プログラムはドットで終わります。あと何かあるとフリーパスカル(FPC/Lazarus)は残りの文字を省略します。

同様の動作が必要です。私はカスタムのモナド トークナイザーを使用していますが、それは怠惰なので、メイン ルールが成功したときに Happy が継続を呼び出さないようにしたいだけです。

基本的に、私はこのようなものを望んでいます:

Program : Header Decls Body '.' SKIP_THE_REMAINING_INPUT { ... }

エラーが発生する可能性があるため、この最後のドットが解析された後はトークン化をまったく行わないことが重要です。

4

1 に答える 1

1

だから私は解決策を見つけました。

Happy には部分解析という機能があり、ドキュメンテーションgit logに記載されていますが、ソース リポジトリを読んで発見しました。これにより、パーサーは残りの入力を破棄できます。とは異なるディレクティブを使用して宣言されてい%nameます。

%name    parser {- normal  parser -}
%partial parser {- partial parser -}

しかし、それが機能する方法は、私の 2 番目の要件に適合しません。怠惰なトークナイザーに入力をこれ以上消費させるべきではありません。代わりに、解析するものがこれ以上ないことを確認するために、あと 1 つのトークンが必要です。

が有効なシンボルではなく、トークナイザーがそれを消費できないと仮定し!、次の入力を検討してください。

  1. begin end. valid_token!!!
  2. begin end.!

Happy は をチェックしてvalid_tokenそこで停止するため、解析 (1) は成功しますが、もう 1 つのトークンが必要なため (そしてトークナイザーがそれを与えることができないため)、解析 (2) は失敗します。

どうやらこの動作を変更する方法はないので、私の回避策は、文法のどこにも現れない特別なトークンによって字句エラーを表すことです。!したがって、トークナイザーが(またはその他の無効な文字) に遭遇すると、特別なエラー トークンが生成されます。また、字句エラーからの回復にも役立つはずです。

于 2014-09-14T14:38:28.443 に答える