ocaml分析器“值不匹配”错误

时间:2018-08-16 12:57:54

标签: parsing ocaml ocamlyacc

我好!

我正在尝试为计算机代数系统编写一个词法分析器和解析器。

用makefile编译代码时,某些函数的值存在问题。

这是function.ml的代码:

  (****************************************
     * Type definitions
     ****************************************)
    type operator = Plus | Minus | Times | Div | Power;;

    type var = string;;                     (* e.g. "x", "y", etc. *)
    type power = var * float;;              (* var, raised_to, e.g. ("x", 3.) -> x^3. *)
    type monomial = float * power list;;    (* coefficient, list of power terms, e.g. (2., [("x", 1.); ("y", 3.)]) -> 2xy^3 *)
    type polynomial = monomial list;;       (* sum of monomials, e.g. [(2., [("x", 2.); ("y", 3.)]); (-1., [])] -> 2x^2y^3 - 1 *)
    type frac = polynomial * polynomial;;   (* numerator, denominator *)
    type exp = frac * frac;;                (* base, exponent *)
    type term = Poly of polynomial
              | Frac of frac
              | Exp of exp;;
    type expr = Leaf of term
              | Node of operator * expr list;;
    type eqn = expr * expr;;

    (****************************************
     * Lexer/Parser definitions
     ****************************************)
    type token = PLUS | MINUS | TIMES | DIV | POWER | LPAREN | RPAREN | EQUALS
               | FLOAT of float
               | VAR of var
               | EOF;;

这是lexer.mll的代码:

{
  open Function
}

let numeric  = ['0' - '9']
let letter   = ['a' - 'z' 'A' - 'Z']

rule main = parse
  | [' ' '\t' '\n'] { main lexbuf }  (* skip over whitespace *)

  | "+"     { PLUS }
  | "-"     { MINUS }
  | "*"     { TIMES }
  | "/"     { DIV }
  | "^"     { POWER }
  | "("     { LPAREN }
  | ")"     { RPAREN }
  | "="     { EQUALS }

  | ((numeric*) '.' (numeric+)) as n 
              { FLOAT (float_of_string n) }

  | (numeric+) as n
    { FLOAT (float_of_string n) }

  | (letter numeric*) as n
    { VAR n }

  | eof         { EOF } 

{
 let lexer_main = main;;

 let token_iterator_of_string s =
   let rec lbuf = Lexing.from_string s
   in fun () -> lexer_main lbuf;;

 let token_list_of_string s =
   let rec lbuf = Lexing.from_string s 
   and token_list_aux () =
     let token = lexer_main lbuf in
     if token = EOF then
       []
     else
       token :: token_list_aux ()
  in token_list_aux ();;
}

这是parser.mly的代码:

   %{
       open Function
     %}
  %token PLUS MINUS TIMES DIV POWER LPAREN RPAREN EQUALS EOF
  %token <float> FLOAT
  %token <Function.var>   VAR
  %start yacc_eqn
  %start yacc_expr
  %type <Function.eqn>  yacc_eqn
  %type <Function.expr> yacc_expr

  %%
  yacc_eqn:
     exp EQUALS exp EOF   { ($1, $3) }

  yacc_expr:
     exp EOF              { $1 }

  exp:
     op1                  { $1 }

  op1:
     op2                  { $1 }
   | op1 PLUS op2         { Node(Plus, [$1; $3]) }
   | op1 MINUS op2        { Node(Minus, [$1; $3]) }

  op2:
     op3                  { $1 }
   | op2 TIMES op3        { Node(Times, [$1; $3]) }
   | op2 DIV op3          { Node(Div, [$1; $3]) }

  op3:
     op4                  { $1 }
   | op3 op4              { Node(Times, [$1; $2]) }

  op4:
     leaf                 { $1 }
   | op4 POWER leaf       { Node(Power, [$1; $3]) }

  leaf:
     atom                 { $1 }
   | LPAREN exp RPAREN    { $2 }

  atom:
     VAR                  { Leaf(Poly(poly_of_var $1)) }
   | FLOAT                { Leaf(Poly(poly_of_float $1)) }

  %%

  let eqn_of_string s  = yacc_eqn  Lexer.lexer_main (Lexing.from_string s);;
  let expr_of_string s = yacc_expr Lexer.lexer_main (Lexing.from_string s);;

  let parse_eqn  = eqn_of_string;; 
  let parse_expr = expr_of_string;;

问题在于,在使用makefile创建的parser.mli中,yacc_eqn和yacc_expr的值是:

    val yacc_eqn :
      (Lexing.lexbuf  -> token) -> Lexing.lexbuf -> Function.eqn
    val yacc_expr :
      (Lexing.lexbuf  -> token) -> Lexing.lexbuf -> Function.expr

我有以下错误:

The implementation parser.ml does not match the interface parser.cmi:
   Values do not match:
     val yacc_eqn :
       (Lexing.lexbuf -> Function.token) -> Lexing.lexbuf -> Function.eqn
   is not included in
     val yacc_eqn :
       (Lexing.lexbuf -> token) -> Lexing.lexbuf -> Function.eqn

我认为解决方案可能是演员阵容,但是我完全不知道该怎么做...有人帮忙吗?

谢谢!

0 个答案:

没有答案