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

我得到两个FunDec带有单例列表的标记,而不是FunDec带有由两个元素组成的列表的单个标记。

如何使用 menhir 解析列表fundec

PS:我知道我可以在第二遍中合并这些列表,但如果可能的话,我希望解析器为我做这件事

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 回答