逆方向、つまり同じ文法仕様からのドメインオブジェクトの解析解除(別名プリティプリンティング)も実装するパーサジェネレーターはありますか?私の知る限り、ANTLRはこれをサポートしていません。
5 に答える
反転可能な構文の説明を見てください:構文解析ときれいな印刷の統合。
JavaとKotlinに一連の可逆パーサーコンビネーターを実装しました。パーサーはほとんどLL-1スタイルで記述されており、解析メソッドと印刷メソッドを提供し、後者はきれいなプリンターを提供します。
プロジェクトはここにあります:https ://github.com/searles/parsing ここにチュートリアルがあります:https ://github.com/searles/parsing/blob/master/tutorial.md そしてここにパーサー/プリティプリンターがあります数式の場合:https ://github.com/searles/parsing/blob/master/src/main/java/at/searles/demo/DemoInvert.kt
私たちのDMSソフトウェアリエンジニアリングツールキットはこれを正確に実行します(そしてコードの分析/変換のための多くの追加サポートを提供します)。これは、言語文法を追加の属性で装飾し、いわゆる属性文法を生成することによって行われます。特別なDSLを使用してこれらのルールを記述し、記述しやすくしています。
DMSが文法に直接基づいてツリーを生成することを知るのに役立ちます。
各DMS文法規則は、いわゆる「プリティプリンティング」規則とペアになっています。各prettyprintingルールは、対応する文法ルールによって認識される構文要素とサブ要素を「prettyprint」する方法を説明します。プリティプリントプロセスは、基本的に、テキストの長方形のボックスを水平または垂直に(オプションのインデントを使用して)製造または結合し、リーフは、リーフのリテラル値(キーワード、演算子、識別子、定数など)を含む単位の高さのボックスを生成します。
例として、次のDMS文法規則と一致するprettyprinting規則を書くことができます。
statement = 'for' '(' assignment ';' assignment ';' conditional_expression ')'
'{' sequence_of_statements '}' ;
<<PrettyPrinter>>:
{ V(H('for','(',assignment[1],';','assignment[2],';',conditional_expression,')'),
H('{', I(sequence_of_statements)),
'}');
これにより、以下が解析されます。
for ( i=x*2;
i--; i>-2*x ) { a[x]+=3;
b[x]=a[x]-1; }
(ステートメントと式に追加の文法規則を使用)、次のようにそれをプリティプリントします(これらの追加の文法規則に追加のプリティプリント規則を使用)。
for (i=x*2;i--;i>-2*x)
{ a[x]+=3;
b[x]=a[x]-1;
}
DMSはまた、コメントをキャプチャし、それらをASTノードに添付して、出力時に再生成します。ほとんどのパーサーはコメントを処理しないため、実装は少しエキゾチックですが、使用は簡単で、「無料」ですらあります。コメントは、元の場所のきれいに印刷された結果に自動的に挿入されます。
DMSは「忠実度」モードで印刷することもできます。この形式では、解析されたトークンの列オフセット(行への)のトークンの形状(たとえば、基数、識別子の文字の大文字化、使用されたキーワードのスペル)を保持しようとします。これにより、元のテキスト(またはそれが異なっているとは思わないほど近いもの)が再生成されます。
プレティプリンターがしなければならないことの詳細は、ASTをソースコードにコンパイルすることに関する私のSOの回答に記載されています。DMSは、これらすべてのトピックに適切に対応します。
この機能は、完全なIBM COBOL、PL / SQL、Java 1.8、C#5.0、C(多くの方言)およびC++14を含む約40以上の実際の言語でDMSによって使用されています。
十分に興味深い一連のprettyprinterルールを作成することで、ハイパーリンクされたソースコードを含むように拡張されたJavaDocなどを構築できます。
アンパーサーの実装を含むパーサージェネレーターがいくつかあります。それらの1つは、文脈自由文法用のニアリーパーサジェネレータです。
明確な句の文法を使用して、ソースコードの双方向変換を実装することも可能です。SWI-Prologでは、述語は入力テキストを解析ツリーに変換でき、その逆も可能です。phrase/2
一般的には不可能です。
何がプリントをきれいにしますか?スペース、タブ、または改行がそれらの位置にある場合、印刷はきれいになり、印刷が見栄えよくなります。
しかし、ほとんどの言語では空白は重要ではないため、ほとんどの文法は空白を無視します。Pythonのような例外はありますが、一般に、構文として空白を使用するのが良いかどうかという問題については、まだ議論の余地があります。そのため、ほとんどの文法は構文として空白を使用しません。
また、抽象構文ツリーに空白が含まれていない場合、パーサーが空白を破棄したため、ジェネレーターはそれらを使用してASTをきれいに印刷できません。