Rascal MPLでSDFの{避け}を使う方法
-
21-12-2019 - |
質問
Rascal Mpl を使用して島の文法を設計しようとしていますが、私は走った問題:
SDFで島の文法を実装するとき、非常に一般的なアプローチは、{避け}属性を使用して「キャッチオール」水の生産を定義することです。これにより、他の人が適用可能であれば、パーサーがこの制作を使用するのを防ぎます。これにより、アビジュイツを生成する他のプロダクションによって上書きできるデフォルトの動作を指定できます。これの非常に簡単な例は次のとおりです。
context free syntax
Chunk* -> Input
Water -> Chunk
lexical syntax
~[\t\n\ ]+ -> Water {avoid} // avoid the Water production
.
私はRascal MPLでこの動作を再現してみました。私の目標は、すべての条件付きプリプロセッサ指令をC / C ++コードの中に集める島の文法を作成し、水産を使用して残りの入力をスキップします。
layout LAYOUT = [\t\n\ ];
lexical WATER = ![\t\n\ ]+;
start syntax Program = Line*; // program consists of lines
syntax Line = ConditionalDirective // preprocessor directives
> WATER; // catch-all option
syntax ConditionalDirective = "#ifdef"
| "#ifndef"
| "#if"
| "#elif";
.
私は条件のDirective プロダクションを ">"演算子を使用してより高い優先順位を与えることによって{避け}効果を作成しようとしましたが、これは明らかには機能しません。解析ツリーはまだあいまいさが含まれています。
#ifdef asd
.
例えば上記のコードを解析する場合は、次のようになっている解析ツリーを入手します。
Rascalからわかります。 「Priority」-Operatorを使用して、Documentation - オペレータが私の場合に行く方法ではないかもしれませんが、他の可能性は見られません。私は、Rascalの著者らはすべてのSDF文法をRascal文法に変換できることを明確に述べるので、私は方法があると思います。
SDFSを再現する方法は、Rascal MPLを使用して機能を避けますか?それとも、どういうわけか優先順位を再適用することは可能ですか?
解決
短時間:SDF2 Aポスト解析フィルタに避けてください。 Rascalでは、これらを定義することができます。
警告:避けては一般的にSDF2で水の挙動を定義するのに十分ではなく、Rascalではありません。その理由は、水がその代替手段よりも長くなる可能性があります。潜伏の長さの観点から、等しい長さの代替案の間でのみ選択することができます。 1つの確保者だがRascalの水に対処するための遅い方法は、すべての代替案でそれを数えることであり、より少ない水で派生化を選択することです。
優先して避けたもう1つの問題は、特にそれらがカウントされたときに、使用が干渉を始めるだろうということでした。これは、特定の非留学団または代替規則のためのフィルターを特化することによって、Rascalでは回避できます。
もう1つのオプションは\と!曖昧さ演算子マニュアルを参照してください。しかし、すべてとすべて 私はPost Parse Filteringオプションは現在、何が起こっているのかを制御するので、現在島の文法に対処するための最良の方法であると思います。