Вот мой текущий лексер и парсер для языка тигра Эндрю Аппеля (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
со списком, состоящим из двух элементов.
Как я могу использовать менгир для анализа списка fundec
?
PS: я знаю, что могу объединить этот список во втором проходе, но я бы хотел, чтобы синтаксический анализатор сделал это за меня, если это возможно.