【问题标题】:OCaml: new_line equivalent before 3.11OCaml:3.11 之前的 new_line 等效项
【发布时间】:2016-06-20 22:31:31
【问题描述】:

我正在尝试在使用 OCaml 3.10 运行 Ubuntu Hardy 的机器上编译 Libra toolkit,我无法升级操作系统或更新 OCaml,而且我对 OCaml 一无所知。只有一行给我一个未绑定值错误,因为它使用了在 OCaml 3.11 (http://caml.inria.fr/pub/docs/manual-ocaml/libref/Lexing.html) 中引入的 new_line 函数,有人可以告诉我如何更改它以兼容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)}

【问题讨论】:

  • 这会有所帮助,它实际上是我想要的功能,但我不知道如何在我的代码中插入它:caml.inria.fr/mantis/view.php?id=3930
  • 我尝试使用这个:(* let start_next_line lexbuf = () *) let start_next_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;} },然后是| ['\n' '\r']+ {start_next_line lexbuf; TEOL},但我得到错误致命错误:异常Data.Eof有时
  • 如果相关,您真的应该将这些包含在您的问题正文中。
  • Data.Eof 问题似乎与您的问题无关:显然您的代码似乎正确(它确实编译,并且与 lexing 中的相同),所以我会尝试查看您的数据是否喂它是正确的,或向维护者报告。请注意,它不是生产就绪代码。
  • 数据是正确的,它适用于 Libra 0.5,但随着加什答案的变化,它会导致该错误。事实上,Libra 有另一个以这种方式工作的文件。 IDK 如果这值得报告,我正在尝试使源代码与旧版本的 OCaml 兼容,除非有人与我处于完全相同的情况,否则它没有用。源码在Libra 0.5.0,有两个文件是这样的:src/mn/mnLexer.mll(第46行)和src/bn/cnLexer.mll(第48行),包含函数的一个是src/ bn/bifLexer.mll(第 27 行)。

标签: compilation makefile ocaml lexical-analysis


【解决方案1】:

在OCaml源(来自SVN或发布的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),你应该没问题。

【讨论】:

  • 我试过了,但我得到了一个分段错误和一些输入文件的“致命错误:异常 Data.Eof”,我在其中看到的唯一一件事是它们可能比其他文件更大.
  • 我刚刚发现我在修改文件时犯了一个错误,我按照你说的做了,并将解析新行的行更改为| ['\n' '\r']+ {new_line lexbuf; TEOL},现在它可以工作了。非常感谢!
【解决方案2】:

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

【讨论】:

  • 我无法安装 OPAM,无法更改 sources.list,并且在尝试使用 curl 下载 ocamlbrew 时出现“无法解析主机”。我可以毫无问题地使用 apt-get,但我不能使用 curl 或 wget。
  • 直接抓取ocaml的源码并编译即可;这并不难。 OPAM 非常棒,因为它更加简化了流程,并且使处理依赖关系变得非常简单,但是如果您没有那么多库要安装,您可以“手动”构建所有内容(即configure &amp;&amp; make &amp;&amp; make install)。您甚至可以查看 debian 包依赖项以了解您需要哪些源(对于除 ocaml lang 之外的所有内容),并使用 debian 打包数据将您的构建与系统正确集成。
  • 既然你用的是Ubuntu,为什么不升级到新版本呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多