1

私は次のバイソン文法を持っています(より複雑な文法の一部として):

expression:
    IDENTIFIER
    | CONST
    | LAMBDA match_block
;
match_block:
    pattern '=' expression
    | match_block '|' pattern '=' expression
;
pattern:
    IDENTIFIER
    | CONST
;
これは、次の例のように、パターンマッチングを使用して識別子、定数、ラムダ関数を含む式を記述します。
lambda 0 = 1
     | 1 = 2
     | x = x
問題は、ネストされた一致とのあいまいさによって引き起こされる1シフト/リデュースの競合です。
lambda 0 = 1
     | x = lambda 1 = 2
                | y = 4
ルールは、一致ブロックが最も近い関数に関連していることです。上記の例ではインデントで示されています。

私の質問は、この文法を書き直して、このあいまいさを排除するにはどうすればよいですか(%left%right yaccディレクティブを使用せずに)?

4

1 に答える 1

2

|を常に最も近いものにバインドしたい場合、それは基本的に、 :のLAST句にLAMBDAのみを含めることができることを意味します。LAMBDA|match_block

non_lambda_expression:
    IDENTIFIER
    | CONST
;
expression:
    non_lambda_expression
    | LAMBDA match_block
;
non_lambda_match_block:
    pattern '=' non_lambda_expression
    | non_lambda_match_block '|' pattern '=' non_lambda_expression
;
match_block:
    pattern '=' expression
    | non_lambda_match_block '|' pattern '=' expression
;
pattern:
    IDENTIFIER
    | CONST
;

基本的に、ラムダを許可するバージョンと許可しないバージョンの2つのバージョンに分割expressionし、あいまいさを避けるために各スポットで適切なバージョンを使用します。match_block

于 2011-05-24T23:49:42.417 に答える