【问题标题】:OCaml: Issue manipulating string read from fileOCaml:问题处理从文件中读取的字符串
【发布时间】:2018-03-15 20:51:36
【问题描述】:

我正在尝试在 OCaml 中逐行读取文件。文件中的每一行都代表我要解析的字符串,采用解析工具所期望的正确格式。我将每一行保存在列表结构中。

我在解析列表的每个元素中包含的字符串时发现了一个问题。我使用 OCamllex 和 Menhir 作为解析工具。

  • 如果我尝试使用print_string 在每个元素处打印列表的内容,我会得到正确的文件内容。

  • 如果我尝试将我在程序中定义的string 传递给函数,那么我会得到所需的输出。

  • 但是,如果我尝试解析刚刚从文件中读取的字符串,则会收到错误消息:Fatal error: exception Failure ("lexing empty token")

注意:所有这些都已针对相同的字符串进行了测试。

这是一个sn-p的代码:

let parse_mon m = Parser.monitor Lexer.token (from_string m)

let parse_and_print (mon: string)=
  print_endline (print_monitor (parse_mon mon) 0)

let get_file_contents file =
  let m_list = ref [] in
    let read_contents = open_in file in
      try
        while true; do
          m_list := input_line read_contents :: !m_list
        done; !m_list
      with End_of_file -> close_in read_contents; List.rev !m_list

let rec print_file_contents cont_list = match cont_list with
  | [] -> ()
  | m::ms -> parse_and_print m

let pt = print_file_contents (get_file_contents filename)

【问题讨论】:

  • 如果不查看您的 lex 模式,您似乎还没有涵盖基本匹配项,例如 eol_。看我的回答。

标签: string file parsing ocaml


【解决方案1】:

当流中的文本与任何扫描仪模式都不匹配时,Ocamllex 会引发异常 Failure "lexing: empty token"。因此,您需要匹配诸如._eof 等“包罗万象”的模式。

{ }
rule scan = parse
  | "hello" as w { print_string w; scan lexbuf }
  (* need these two for catch-all *)
  | _ as c       { print_char c; scan lexbuf }
  | eof          { exit 0 }

【讨论】:

    【解决方案2】:

    没有看到您的语法和文件,我只能提供一个疯狂的猜测:文件是否在末尾包含一个空行?取决于可能导致您看到的错误的.mll。原因是get_file 将新行追加到列表的前面,而print_file_contents 只查看该列表的头部。

    【讨论】:

    • 是的,你是对的,但是在get_file_contents 我正在反转列表,所以列表的第一个元素不会是空行。此外,我只是出于测试目的打印列表的头部 - 所以我不应该遇到空行。其次,我尝试输出列表的元素数量,并且每一行都有一个,所以我也不认为最后的空行被附加了。
    【解决方案3】:

    我同意kne,很难说没有看到文件,但你可以做的是尝试隔离导致问题的行:

    let rec print_file_contents cont_list = 
      match cont_list with
      | []    -> ()
      | m::ms -> 
        try parse_and_print m
        with Failure _ -> print_string m
    

    【讨论】:

    • 感谢您,但这似乎不是一个选项,因为所有输入字符串都失败了。正如我在 kne 的回复中提到的,我的列表中没有填充空元素,如果输入字符串在程序中作为参数传递,那么函数可以正常工作跨度>
    • 是否可以查看您的语法(.mly 文件和 .mll 文件),此外,查看您正在运行测试的文件会很有用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    相关资源
    最近更新 更多