1

我正在尝试在使用 OCaml 3.10 运行 Ubuntu Hardy 的机器上编译Libra 工具包,我无法升级操作系统也无法更新 OCaml,而且我对 OCaml 一无所知。只有一行给我一个未绑定的值错误,因为它使用了OCaml 3.11 中引入的new_line函数(http://caml.inria.fr/pub/docs/manual-ocaml/libref/Lexing.html) ,有人可以告诉我如何将其更改为与 OCaml 3.10 兼容吗?这是该代码末尾附近的行:

{
open MnParseTypes;;
open MnParser;;
(* Raised when parsing ends *)
exception Eof;;

module L = Lexing
let linenum lexbuf = lexbuf.L.lex_curr_p.L.pos_lnum

let line = ref 1;;

let keywords = Hashtbl.create 10
let _ = 
  List.iter2 (Hashtbl.add keywords)
    ["mn"; "features"; "tree"; "table"; "w"; "eof"]
    [Tmn; Tfeatures; Ttree; Ttable; Tweight; EOF];;
}

let digits = ['0'-'9']+
let identifier = ['a'-'z' 'A'-'Z']+

rule lexer = parse
(* eat blank characters *)
    [' ' '\t'] {lexer lexbuf}
(* | "Feature list:" {lexer lexbuf} *)
  | '{' {Tlbrace}
  | '}' {Trbrace}
  | '(' {Tlparen}
  | ')' {Trparen}
  | ('-')? "inf" {Tfloat( float_of_string(L.lexeme lexbuf))}
  | identifier {
      let x = String.lowercase (Lexing.lexeme lexbuf) in
      try Hashtbl.find keywords x
      with Not_found -> 
        failwith((Lexing.lexeme lexbuf) 
          ^ ": unknown identifier on line " ^ string_of_int (linenum lexbuf))}
  | digits {Tint (int_of_string (L.lexeme lexbuf))}
  | ('-')? digits ('.' digits)? (['e' 'E'] ['+' '-']? digits)? 
      {Tfloat( float_of_string(L.lexeme lexbuf))}
  | '+' 'v' (digits as var) '_' (digits as value) 
      {Tcond(true, int_of_string var, int_of_string value)}
  | '-' 'v' (digits as var) '_' (digits as value) 
      {Tcond(false, int_of_string var, int_of_string value)}
  | 'v' (digits as var) '_' (digits as value) 
      {Tvar( int_of_string var, int_of_string value)}
  | ['\n' '\r']+ {L.new_line lexbuf; TEOL}   (* THIS GIVES THE ERROR *)
  | eof {EOF}
  | _ {failwith((L.lexeme lexbuf) ^ 
       ": mistake on line " ^ string_of_int lexbuf.L.lex_curr_p.L.pos_lnum)}
4

2 回答 2

3

在OCaml源(来自SVN或relase tarball)的目录中,Foo标准库模块的源将在stdlib/foo.{ml,mli}.mli是接口文件,.ml实现文件)。看着stdlib/lexing.ml给你:

let new_line lexbuf =
  let lcp = lexbuf.lex_curr_p in
  lexbuf.lex_curr_p <- { lcp with
    pos_lnum = lcp.pos_lnum + 1;
    pos_bol = lcp.pos_cnum;
  }

您也可以在您的代码中实现这一点,使用open Lexing将字段名称包含在范围内,或者使用lexbuf.Lexing.lex_curr_p,{ lcp with Lexing.pos_lnum = lcp.Lexing.pos_lnum ...代替。

编辑:因为您可能不打算自己破解 OCaml 代码,所以让我们给您完整的内容:

let new_line lexbuf =
  let lcp = lexbuf.Lexing.lex_curr_p in
  lexbuf.Lexing.lex_curr_p <- { lcp with
    Lexing.pos_lnum = lcp.Lexing.pos_lnum + 1;
    Lexing.pos_bol = lcp.Lexing.pos_cnum;
  }

将此添加到使用的文件的顶部new_line(如果它显示Lexing.new_line,请将其转换为new_line),您应该没问题。

于 2013-05-12T07:29:37.027 回答
2

你可以new_line自己实现,但我认为升级 OCaml 会更好。我知道您说过您不能升级操作系统,但可以在您的主目录中安装更新版本的 Ocaml,而无需任何超级用户权限。OPAM是 OCaml 的数据包管理器,可以非常轻松地安装最新版本的 OCaml。

于 2013-05-12T08:24:27.520 回答