Тип Ocaml Ошибка в операторе возврата рекурсивной функции - PullRequest
0 голосов
/ 10 ноября 2018

У меня есть синтаксический анализатор, написанный от руки. Каждый нетерминал имеет соответствующий метод синтаксического анализа. Каждый метод синтаксического анализатора имеет тип tokenlist -> tokenlist * Ast`

Внутри каждого метода я использую соглашение "tokenlist_symbol" для обозначения списка токенов после использования определенного символа. В этой строке: let typ tokenlist_typ = parseTyp tokenlist in match tokenlist.head with, typ - это AST, а tokenlist_typ - остаток списка токенов после того, как parseTyp использует префикс typ.

Однако я получаю This expression has type 'a -> token_list * Ast.typ but an expression was expected of type Ast.typ ошибку для строки, (Ast.Declaration(typ, identifier, decls_prime), tokenlist_decls_prime)

type token_list = 
  {head : Lexer.token; (** head token. *)
   lexbuf : Lexer.token list}  (** lexer buffer. *)
(** Represents a parser buffer used during parsing of various productions. *)

let default_tokenlist s = {head = Lexer.EOF; lexbuf = Lexer.tokenize s}
(* Create a default [parse_buffer] with the given string [s]. *)

let next tokenlist =
    let {head = _; lexbuf = buf} = tokenlist in
    {head = List.hd buf; lexbuf = List.tl buf}
(** Retrieves a new parser buffer with the next lookahead token. *)

let parseTyp tokenlist = 
    match tokenlist.head with 
    | Lexer.Int -> (next tokenlist, Ast.Int) 
    | Lexer.Bool -> (next tokenlist, Ast.Bool)
    | Lexer.Void -> (next tokenlist, Ast.Void)  
    | Lexer.EOF -> (tokenlist, Ast.Epsilon)
    | _-> let err_msg = "Syntax Error" in
          raise (Syntax_error err_msg)

(*decls = typ “id” decls_prime | epsilon *)
let rec parseDecls tokenlist = 
    let (tokenlist_typ, typ, ) = parseTyp tokenlist in 
        match tokenlist.head with 
        | Lexer.ID identifier -> let (tokenlist_decls_prime, decls_prime) = next tokenlist |> parseDeclsPrime in 
                                (tokenlist_decls_prime, Ast.Declaration(typ, identifier, decls_prime))
        | Lexer.EOF -> (tokenlist, [])
        | _-> let err_msg = Printf.sprintf "Syntax Error" in
              raise (Syntax_error err_msg)

(* decls_prime = vdecl decls | fdecl decls *)
and parseDeclsPrime tokenlist =
    match tokenlist.head with 
    | Lexer.Semicolon -> let tokenlist_vdecl) = next tokenlist in
                let (tokenlist_decls, decls) = parseDecls tokenlist_vdecl in 
                (tokenlist_decls, Ast.DeclsPrime(Lexer.Semicolon, vdecl, decls)) 
    | Lexer.LeftParens -> let (tokenlist_fdecl, fdecl) = next tokenlist |> parseFdecl in 
                let (tokenlist_decls, decls) = parseDecls tokenlist_fdecl in 
                (tokenlist_decls, Ast.DeclsPrime(Lexer.Semicolon, fdecl, decls)) 
    | _-> let err_msg = Printf.sprintf "Syntax Error" in
          raise (Syntax_error err_msg)

1 Ответ

0 голосов
/ 10 ноября 2018

У вас есть это:

let (decls_prime, tokenlist_decls_prime) = 
    next tokenlist |> parseDeclsPrime

Судя по именам, похоже, parseDeclsPrime возвращает тип Ast * tokenlist. Но мне кажется, что функции синтаксического анализа должны возвращать tokenlist * Ast.

Скорее всего, два имени в паре поменялись местами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...