如何使用 menhir 解析表达式列表?
How to parse list of expression using menhir?
这是我目前的 lexer and parser 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:我知道我可以在第二次合并这些列表,但我希望解析器尽可能为我做这件事
由于一组函数没有标记,你必须自己声明你的列表,有几个构造函数:
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
对应"any list of declaration that does not start with a function"。请注意,单个函数声明将位于单个元素列表中。
这是我目前的 lexer and parser 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:我知道我可以在第二次合并这些列表,但我希望解析器尽可能为我做这件事
由于一组函数没有标记,你必须自己声明你的列表,有几个构造函数:
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
对应"any list of declaration that does not start with a function"。请注意,单个函数声明将位于单个元素列表中。