2

s00、s01、s10、s11 の 4 種類のステートメントを含む言語があります。先頭の 1 は最初のキーワードを意味し、末尾の 1 は終了を意味し、区切り記号「;」があります。「;」でステートメントを終了できます。「;」の使用を最小限に抑えるステートメントのリストを許可する言語を解析したいと思います。パーサーは GLR+ である Dypgen です。

例:

{ x=1 fun f(){} x=1; x=1 var x=1 var x=1; x=1 }

これを行うことはまったく可能ですか?もしそうなら、どのように?そうでない場合、なぜですか?

主にそれを行う方法を考えられないため、それを行うことはできないと思います:)しかし、それは文脈に依存しているようです:ルールは、「;」を挿入する必要があるということです。A が終了せず、B が開始されていない場合は、A と B の間で、B と C についても同様で、B が 2 回使用されることを意味します。

ただし、パーサーは GLR+ であるため、単純に使用したくなる

(s00|s01|s10|s11}*

ルールとして、そしてそれが誤って解析された場合は「;」をスローします (これは s11 no-op です) あいまいさを解決します。ただし、パーサーが構文エラーを報告する方がよいでしょう。おそらくこれは、代替のプロダクションをマージするときに実行できます。本当の問題は、マージではなくオーバーラップする場合です。これが発生すると、プログラムの解析が爆発する可能性があります。

4

1 に答える 1

1

私は最近、トップレベルのフレーズで同様の問題を抱えており ;;、前のフレーズで終了する必要があるものもあれば、そうでないものもあります (フレーズを導入するキーワードで始まる)。フレーズの構文カテゴリを 2 つに分割し、この動作を表現するフレーズ シーケンスに細かいルールを与えることで、問題を解決しました。しかし、これは分割された文法の重複をもたらしました。

あなたの場合、それは次のようになります:

sequence:
  | (s00 | s10) sequence_closed
  | (s01 | s11) sequence_open
  | ε

sequence_closed:
  | s10 sequence_closed
  | s11 sequence_open
  | ';' sequence_open
  | ε

sequence_open:
  | s00 sequence_closed
  | s01 sequence_open
  | ε

余分な区切り文字を許可したい場合 (そしておそらくそうしたい場合) はもう少し複雑ですが、それがアイデアです。

于 2010-12-18T20:52:38.117 に答える