音楽プログラミング言語を設計し、その構文を PEG 文法として実装しています。構文解析プロセスはかなり複雑になりました。そのため、最も単純なアプローチのように見えたのは、いくつかの個別の文法を定義し、それらを順番に適用することでした。これまでのところ、3 つの文法があります。
- ソース ファイルの内容全体を取得し、コメントを削除します。
- ソース ファイル (コメントを削除) を取得し、楽器ごとに分けます。これにより、楽器の名前/定義と、その楽器によって「演奏される」「音楽コード」のペアが作成されます。
- 実際に音楽コードを解析し、音楽の「イベント」の解析ツリーを返します。
3 つのパーサーのうち、#3 は群を抜いて最も複雑です。#1 と #2 は比較すると単純で、それぞれ約 10 行しか使用しません。一方、#3 は、実装する構文が増えるほど複雑になり、現在 33 行に増えています。
3 つの文法を 1 つに凝縮できるのではないかという考えが頭に浮かびました。これにより、文法の繰り返しが少し減るかもしれませんし、プログラム自体のコードの行数も減るかもしれませんが、物事が過度に複雑になるかどうかはわかりません。私はそれらを組み合わせることに大雑把に突き刺しましたが、すべてのルール内でコメントが発生する可能性に対処する必要があるように思われるため、すぐに難しいことがわかりました(間違っていたら訂正してください!)。現状では、オプションの空白の規則が既にあり、ほとんどの音楽の「イベント」の定義に含めて、構文で空白をある程度柔軟に使用できるようにしています。複数のパスでの解析に固執し、タスクごとに 1 つずつ、複数の個別のパーサーを用意する方が理にかなっているのかどうか、私には判断できません。
私の質問は次のとおりです。PEG 文法を作成した経験のある方は、大きな文法を小さなサブ文法に分割し、入力に対して複数のパスを作成することがよくありますか? すべてを 1 つの文法にまとめることの利点 (パフォーマンスまたはその他) はありますか?