これは、言語設計で使用される概念をフレームワークの形で抽象化することを目的とした抽象化プロジェクトへの姉妹プロジェクトに焦点を当てた一連の質問の一部です。姉妹プロジェクトはOILexerと呼ばれ、一致時にコードインジェクションを使用せずに、文法ファイルからパーサーを構築することを目的としています。
構造タイピングに関連するこれらの質問に関連する他のいくつかのページを表示できます ここ 、および使いやすさ ここ が見つかります。フレームワークに関する問い合わせに関連するメタトピックと投稿する適切な場所は、 ここ で見つけることができます。
特定の文法から解析ツリーの抽出を開始するところまで来ています。その後、DFAを使用して順方向パスを識別する再帰的降下パーサーが続きます(ANTLR 4のLL(*)と同様)。私はそれを開いて洞察を得ようと考えました。
これまでのところ、実装されているものの簡単な概要です:
実装されていないのはCST生成です。これを機能させるには、適切なコンテキストを引き継ぐように決定論的自動化を調整する必要があります。
興味のある方のために、私は T *y♯プロジェクトの元の形式 のかなり印刷されたものをアップロードしました。各ファイルは他のすべてのファイルにリンクする必要があります。それらに従うために個別のルールでリンクを開始しましたが、時間がかかりすぎました(自動化の方が簡単だったでしょう)。
さらにコンテキストが必要な場合は、それに応じて投稿してください。
2013年5月14日編集:特定の言語で状態マシンのGraphVizグラフを作成するコードを記述しました。 AssemblyPartのGraphVizダイグラフです 。言語の説明でリンクされたメンバーは、相対ルールに、そのルールのダイグラフを含むrulename.txtが必要です。例を投稿してから、言語の説明の一部が変更されました。これは、文法に関することを単純化するためです。ここに興味深い graphviz画像 があります。
これは素晴らしい質問です。
私は最近多くの解析に取り組んできました、そして私見の主な機能のいくつかは:
プログラムAPI-理想的にはライブラリをインポートするだけで、プログラミング言語内から使用できます。 GUIまたはBNFのようなインターフェイスも使用できますが、ツール、IDE、静的分析、テスト、言語抽象化機能、プログラマーの親しみやすさ、ドキュメントジェネレーター、ビルドプロセスを再利用できるため、プログラム的なインターフェイスが重要です。加えて、小さなパーサーでインタラクティブに遊ぶことができるため、学習曲線が劇的に減少します。これらの理由により、「重要な機能」リストの一番上に配置されています。
@guyshermanが述べたように、エラー報告。エラーが見つかったとき、エラーがどこにあり、それが起こったときに何が起こっていたかを知りたいのです。残念ながら、バックトラックが発生したときに適切なエラーを生成する方法を説明するための適切なリソースを見つけることができませんでした。 (ただし、以下の@ Sk-logicのコメントに注意してください)。
部分的な結果。解析が失敗した場合、エラーの場所の前にあった入力の部分から何が正常に解析されたかを確認できるようにしたいです。
抽象化。十分な機能を組み込むことはできず、ユーザーは常にさらに多くの機能を必要とするため、考えられるすべての機能を事前に理解しようとすると失敗します。これはテンプレートとはどういう意味ですか?
私はあなたの#2(先読み予測)に同意します。良いエラーレポートを生成するのに役立つと思います。それは他の何かに役立ちますか?
解析が発生したときに解析ツリーを構築するためのサポート。
ある種のロギング。これについてはよくわかりません。 (たとえば)トークンを使用してHTMLドキュメントを生成する場合に備えて、パーサーが試行したルールのトレースを表示したり、空白やコメントなどのジャンクトークンを追跡したりできます。
文脈依存言語を処理する能力。これがどれほど重要かわからない-実際には、文脈自由文法を使用して言語のスーパーセットを解析し、その後の追加のパスで文脈依存制約をチェックする方がきれいに思えます。
カスタムエラーメッセージ。特定の状況でエラーレポートを調整し、おそらくより迅速に問題を理解して修正できるようにします。
一方、現在の進捗状況については最新ではありませんが、エラー修正は特に重要だとは思いません。私が気づいた問題は、ツールが提供する潜在的な修正が1)非常に多いこと、2)実際に行われた間違いに対応していないこと、そしてそれほど役に立たないことです。うまくいけば、この状況が改善する(またはおそらくすでに改善している)でしょう。
私は言語設計の経験はありませんが、作成中にパーサーを作成するのに一度はかかりました。ゲームエンジン用にIDE=を作成していました。
私の意見では、最終的なエンドユーザーにとって重要なのは、意味のあるエラーメッセージです。特に地面を壊すポイントではないことは知っていますが、逆に言えば、これが重要な意味を持つことの1つは、誤検知を回避できる必要があるということです。誤検知はどこから発生しますか?それらは、最初のエラーでパーサーが転倒し、完全に回復することはありません。 C/C++はこのことで悪名高くなっています(ただし、新しいコンパイラは少し賢くなっています)。
代わりに何が必要ですか?ある時点で何が有効であるかを知るだけでなく、何が無効であるかを知り、それを有効にするための最小限の変更を行う方法を知っておく必要があると思います。混乱している再帰的な降下に。この情報を生成できるパーサーを構築できると、非常に堅牢なパーサーが提供されるだけでなく、パーサーを使用するソフトウェアにいくつかの素晴らしい機能が提供されます。
これが事実である場合、私は本当に難しい、または愚かに明白な何かを申し訳なく思っているかもしれないことに気づきます。これがあなたが探している種類のものではない場合、私は喜んで私の答えを削除します。
文法には、「再帰ルールを残してはいけない」などの制限があってはなりません。今日広く使われているツールがこれを持っていて、吸い込みLL文法しか理解できないことはばかげています-yaccが正しく行ってからほぼ50年後。
正しい再帰の例(yacc構文を使用):
list:
elem { $$ = singleton($1); }
| elem ',' list { $$ = cons($1, $2); }
;
左再帰の例(yacc synatxを使用):
funapp:
term { $$ = $1; }
| funapp term { $$ = application($1, $2); }
;
さて、これは他の何かに「リファクタリング」されるかもしれませんが、どちらの場合でも、特定の種類の再帰はこれを書くための「正しい」方法です。 。
すべてを「リファクタリング」して、ツールが1つに課す左/右の再帰的フォームであることを要求する代わりに、高度なツールから物事を書き留める自然な方法をサポートすることが期待できます。