OCaml-lex:nots';无论如何,这根本不起作用
我在这里已经穷途末路了。我在Ocamlex找不到任何工作,这让我发疯。这是我的OCaml-lex:nots';无论如何,这根本不起作用,ocaml,ocamllex,Ocaml,Ocamllex,我在这里已经穷途末路了。我在Ocamlex找不到任何工作,这让我发疯。这是我的.mll文件: { open Parser } rule next = parse | (['a'-'z'] ['a'-'z']*) as id { Identifier id } | '=' { EqualsSign } | ';' { Semicolon } | '\n' | ' ' { next lexbuf } | eof { EOF } 以下是我作为输入传入的文件的内容: a=b;
.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解析器,没有人能够发现代码的问题,因为您的lexer工作得非常好 我已经冒昧地编写了以下微型解析器(parser.mly),它构造了一个标识符对列表,例如输入“a=b;”应该给出单例列表[(“a”,“b”)] 代码应该编译(例如ocamlbuild main.byte),没有任何抱怨,并且程序应该按照承诺输出“a=b;”
针对最新编辑: 一般来说,我不认为捕获用于指示失败或误用(如无效参数或失败)的标准库异常是一个好主意。原因是它们在整个库中被广泛使用,因此您通常无法判断是哪个函数引发了异常以及它为什么会引发异常 此外,您正在丢弃唯一有用的信息:错误消息!错误消息应该告诉您问题的来源(我的最佳猜测是与IO相关的问题)。因此,您应该打印错误消息,或者让异常传播到顶层。就我个人而言,我更喜欢后者 但是,您可能仍然希望以优雅的方式处理语法形式不正确的输入。为此,您可以在lexer中定义一个新的异常,并添加一个捕获无效令牌的默认案例
{
exception Unexpected_token
}
...
| _ {raise Unexpected_token}
现在,您可以在主文件中捕获新定义的异常,与以前不同,该异常特定于语法无效的输入。因此,您知道异常的来源和原因,从而有机会做一些比以前更有意义的事情
一个相当随机的OCaml开发提示:如果在编译程序时启用了调试信息,那么将环境变量设置为“b”(例如export OCAMLRUNPARAM=b)将启用未捕获异常的堆栈跟踪 顺便说一句,ocamlex还可以对正则表达式中的“一个或多个”执行
+
运算符,因此
['a'-'z']+
相当于你的
['a'-'z']['a'-'z']*
我正在努力解决同样的问题(这就是我发现这个问题的原因),但最终意识到我错误地将输入文件的路径指定为
Sys.argv.(0)
,而不是Sys.argv.(1)
!笑
我真的希望能有帮助!:) 看起来正则表达式中有一个空格用于标识符。这可以防止lexer识别a=b,尽管它仍然应该识别a=b 你能提供一个ML文件,在这里你定义了像标识符这样的构造函数吗?另外,您能确认ocamlex和ocamlc在编译时没有抱怨吗?它们在parser.mly中被定义为标准,并且也没有抱怨。@marsolk:我很好奇,您知道吗?问题是什么?我想我应该提到,在尝试了这么长时间之后,我现在只是在没有解析器的情况下测试它,它仍然会给我这个错误。我会用我的主文件中的代码编辑帖子;在本例中,我得到了
失败(“lexing:empty token”)
,我查找它意味着它看到了一个与lexer中的任何内容都不对应的字符。最后,我加入了另一条规则:|作为c{Printf.Printf“未识别的字符:%c\n”c;raise(Failure“”)}
,现在它打印“未识别的字符:a”。不过,我将尝试使用调试信息来查看发生了什么。
['a'-'z']+
['a'-'z']['a'-'z']*