OCaml lex : doesn't work at all, 无论如何

标签 ocaml ocamllex

我在我的绳索的尽头。我无法在 ocamllex 中进行任何工作,这让我发疯。这是我的 .mll文件:

{

open Parser

}

rule next = parse
  | (['a'-'z'] ['a'-'z']*) as id { Identifier id }
  | '=' { EqualsSign }
  | ';' { Semicolon }
  | '\n' | ' ' { next lexbuf }
  | eof { EOF }

以下是我作为输入传入的文件内容:
a=b;

然而,当我编译并运行这个东西时,我在第一个字符上得到一个错误,说它无效。老实说,我不知道发生了什么,谷歌根本没有帮助我。这怎么可能?正如你所看到的,我真的被难住了。

编辑:

我工作了很长时间,以至于我放弃了解析器。现在这是我的主文件中的相关代码:
let parse_file filename =
  let l = Lexing.from_channel (open_in filename) in
    try
      Lexer.next l; ()
    with
      | Failure msg ->
        printf "line: %d, col: %d\n" l.lex_curr_p.pos_lnum l.lex_curr_p.pos_cnum

打印出“行:1,列:1”。

最佳答案

如果没有相应的 ocamlyacc 解析器,由于您的词法分析器工作得非常好,没有人能够发现您的代码的问题!

我冒昧地编写了以下构造标识符对列表的小型解析器 (parser.mly),例如输入“a=b;”应该给出单例列表 [("a", "b")]。

%{%}

%token <string> Identifier
%token EqualsSign
%token Semicolon
%token EOF

%start start
%type <(string * string) list> start

%%

start:
| EOF {[]}
| Identifier EqualsSign Identifier Semicolon start {($1, $3) :: $5}
;

%%

为了测试解析器是否如我所愿,我们创建了另一个文件 (main.ml) 来解析字符串“a=b;”并打印结果。
let print_list = List.iter (fun (a, b) -> Printf.printf "%s = %s;\n" a b)
let () = print_list (Parser.start Lexer.next (Lexing.from_string "a=b;"))

代码应该可以编译(例如 ocamlbuild main.byte)而没有任何提示,并且程序应该输出“a=b;”按照 promise 。

回应最新的编辑:

一般而言,我不认为捕获旨在指示失败或误用(如 Invalid_argument 或 Failure)的标准库异常是一个好主意。原因是它们在整个库中无处不在,因此您通常无法分辨哪个函数引发了异常以及为什么会这样。

此外,您丢弃了唯一有用的信息:错误消息!错误消息应该告诉您问题的根源是什么(我最好的猜测是与 IO 相关的问题)。因此,您应该打印错误消息或让异常传播到顶层。就我个人而言,我更喜欢后一种选择。

但是,您可能仍然希望以优雅的方式处理语法错误的输入。为此,您可以在词法分析器中定义一个新的异常并添加一个捕获无效标记的默认情况。
{
  exception Unexpected_token
}
...
| _ {raise Unexpected_token}

现在,您可以在主文件中捕获新定义的异常,并且与以前不同,该异常特定于语法无效的输入。因此,您知道异常的来源和原因,让您有机会做比以前更有意义的事情。

一个相当随机的 OCaml 开发提示:如果在启用调试信息的情况下编译程序,设置环境变量 OCAMLRUNPARAM to "b"(e.g. export OCAMLRUNPARAM=b) 为未捕获的异常启用堆栈跟踪!

关于OCaml lex : doesn't work at all, 无论如何,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5447217/

相关文章:

ocaml - 如何将模块映射到 OCaml 中的模块类型?

haskell - 相当于 OCaml 中的 haskell 的 zipwith

functional-programming - Ocaml - Lazy.force

parsing - 使用 ocamllex/ocamlyacc 解析部分语法

ocaml - ReScript 中的无限列表/流

parsing - 一种解析 sexp 的优雅方式

ocaml - 指定 ocamllex 编码

python - Python 到 CIL(C 中间语言)的翻译

regex - 如何在 OCaml 中使用 "match with"和正则表达式匹配字符串?

ocaml - 将 ocamlyacc 与 sedlex 结合使用