1

現在、プログラミング言語用の(非常に)小さなインタープリター/コンパイラーを作成しようとしています。言語の構文を設定したので、言語の文法を書き留める必要があります。少し調査した結果、LL(1) パーサーが最も使いやすいと思われるため、LL(1) パーサーを使用するつもりです。

私はこの分野には不慣れですが、収集した内容から、BNF または EBNF を使用して構文を形式化することを強くお勧めします。ただし、すべての文法が LL(1) パーサーを使用した実装に適しているわけではないようです。したがって、LL(1) 形式で文法を記述するための正しい (または推奨される) アプローチは何かと考えていました。

助けてくれてありがとう、チャーリー。

PS: Haskell の Parsec ライブラリを使用してパーサーを作成するつもりです。

編集: また、SK ロジックによると、Parsec は無限先読み (LL(k) ?) を処理できますが、質問は依然としてそのタイプの文法を表していると思います。

4

3 に答える 3

3

LR(0) パーサーを使用して同様の小さなプロジェクトを作成しただけなので、私はこれについての専門家ではありません。私がお勧めする一般的なアプローチ:

  1. 算数を機能させます。これにより、+, -, /, *etc のルールと派生を作成し、パーサーが機能する抽象構文ツリーを生成することを確認します。異なる入力でツリーをテストおよび評価して、算術が正しく行われることを確認します。一歩一歩物事を作る。競合が発生した場合は、先に進む前にまずそれを解決してください。

  2. より単純な構成体のように機能しif-then-elseたり、case式が機能したりします。

  3. さらに進むことは、文法を書いている言語によって異なります。

他のプログラミング言語の文法を参照として確認してください (残念ながら、オンラインでどの言語の完全な LL 文法も 1 分で見つけられませんでしたが、LR 文法も参照として役立つはずです)。例えば:

ANSI C 文法

Python 文法

そしてもちろん、ウィキペディアの LL 文法についてのいくつかの小さな例ウィキペディア LL パーサーは、おそらく既にチェックアウトしたことでしょう。

この内容のいくつかが役立つことを願っています

于 2011-02-18T14:11:52.400 に答える
2

文法が LL(k) かどうかを判断するための両方のアルゴリズムがあります。パーサージェネレーターはそれらを実装します。可能であれば、文法を LL(k) に変換するヒューリスティックもあります。

ただし、単純な言語を LL(1) に制限する必要はありません。ほとんどの最新のパーサー ジェネレーター ( JavaCCANTLRPyparsingなど) は LL(k) 内の任意の k を処理できるためです。

さらに重要なことは、言語に最適と考える構文にkは 2 から 4 の間の値が必要である可能性が非常に高いということです。

于 2011-02-27T17:53:54.337 に答える
1

まず、文法を LL(1) にする必要はありません。パーサーの作成が簡単になり、パフォーマンスが向上する可能性がありますが、一般的に使用される言語 (通常は LL(1) ではない) よりも冗長になる可能性が高いことを意味します。

よろしければ、次のステップは、頭の中で文法を調べ、その時点で現れる可能性のあるすべての可能性を想像し、それらが最初のトークンで区別できるかどうかを確認することです。

文法 LL(1) を作成するには、2 つの主要な経験則があります。

  1. 特定の時点で複数の選択肢が表示され、それらが同じトークンで始まる場合は、前にキーワードを追加して、どの選択肢が選択されたかを示します。
  2. オプションまたは繰り返し部分がある場合は、オプション/繰り返し部分の最初のトークンとして表示できない終了トークンが後に続くことを確認してください。
  3. 製作初期のオプションパーツは極力避けてください。これにより、最初の 2 つの手順がはるかに簡単になります。
于 2015-12-04T15:38:46.307 に答える