1

Rascal で、プロダクションのオプション部分の位置にレイアウトがあると曖昧になるのはなぜですか? たとえば、"{ }"はあいまいですが、次の文法からのようStart1にうまく解析Start2されますが、まったく同じであると予想されます。

layout Layout                               = " "?;
start syntax Start1                         = "{" "c"? "}";
start syntax Start2                         = "{" "c" "}"
                                            | "{" "}";

さらに、同じあいまいさを引き起こさない、Start2以外の重複なしで表す別の方法があるかどうかを知りたいです。Start1

明らかに、このコードには大量の重複はなくStart2、ここでは適切なオプションですが、これは単なる例です。私は、3 つまたは 4 つのオプション部分を含む多くのプロダクションを含む文法を扱っています。最後のケースでは、表示されている表記法でStart2すでにプロダクションのオプションではない部分を 2^4=16 回複製する必要があり、これは私の意見では本当に面倒です。 .

4

1 に答える 1

1

文法は、パーサーが次のようなものに生成される前に最初に拡張されます。

layout Layout                         = " "?;
syntax " "?                           =  | " ";
syntax Start1                         = "{" Layout "c"? Layout "}";
syntax "c"?                           =  | "c";
lexical " "                           = [\ ];
lexical "c"                           = [c];
lexical "{"                           = [{];
lexical "}"                           = [}];
syntax Start2                         = "{" Layout "c" Layout "}"
                                      | "{" Layout "}";
syntax start[Start1] = Layout Start1 Layout;
syntax start[Start2] = Layout Start2 Layout;

したがって、{ }(カーリー間のスペース) のような入力の場合、スペースは、Start1 ルールの右側にある Layout の最初のインスタンス、または Layout の 2 番目のインスタンスによって導出できます。パーサーはすべての派生ツリーを生成するため、この場合は両方とも、いわば解析があいまいです。

通常、あいまいさは、次のようなフォロー制限を使用して貪欲さを導入することで解決されます。

layout Layout = " "? !>> " "

または(同等に)次のように:

layout Layout = " "? !>> [\ ]

この制限は、レイアウト ルールの制約として機能します。その後にスペースがある場合、(空の文字列でさえも) 何も派生しません。これにより、最初の派生のみが有効になり、Start1 の最初の Layout インスタンス内にスペースが入ります。この後}、制約を満たすものがあり、解析は明確です。

于 2016-07-06T14:45:54.083 に答える