1

以下は、Andrew Appel の Tiger 言語 (ocaml) 用の現在のレクサーパーサーです。

現在、相互再帰関数をサポートしようとしていますが、次のパーサー コードが機能しません。

decs :
    | l = list(dec) { l }

dec :
    | t = nonempty_list(loc(tydec)) { S.TypeDec t }
    | v = loc(vardec) { S.VarDec v }
    | f = nonempty_list(loc(fundec)) { S.FunDec f }

%inline fundec :
    | Function fun_name = symbol LPar params = tyfields RPar
        Eq body = loc(exp) {
        S.{ fun_name; args = params; return_type = None; body }
    }
    | Function fun_name = symbol LPar params = tyfields RPar
        Colon result_type = symbol Eq body = loc(exp) {
        S.{ fun_name; args = params; return_type = Some result_type; body }
    }

小さな例:

let
    function f1(x : int) : int =
        f2(x)

    function f2(x : int) : int =
        f1(x)

in
    f1 (0)
end

2 つの要素で構成されるリストをFunDec持つ単一のトークンではなく、シングルトン リストを持つ2 つのトークンを取得します。FunDec

menhir を使用して のリストを解析するにはどうすればよいfundecですか?

PS: 2 番目のパスでこれらのリストをマージできることはわかっていますが、可能であればパーサーにマージしてもらいたいです。

4

1 に答える 1

2

関数のグループにはマーカーがないため、いくつかのコンストラクターを使用して、自分でリストを宣言する必要があります。

decs :
    | hd=nonempty_list(fundec) tl=decs_no_function { (S.Fundecs hd)::tl }
    | l=decs_no_function { l }

decs_no_functions :
    | hd=dec tl=decs { hd::tl } (* dec same as yours, without functions *)
    | { [] }

ここでdecs_no_functionsは「関数で始まらない任意の宣言のリスト」に相当します。単一の関数宣言が単一の要素リスト内にあることに注意してください。

于 2017-11-21T13:35:40.287 に答える