我正在尝试实现一个读取正则表达式的解析器。它要求用户输入字符串/整数/浮点的有效输入。如果有效且用户按ctrl^d,则打印号码。否则显示错误。但当我按下ctrl^D时,以下代码中的问题并没有停止。如何实现eof令牌并打印输入?
test.mll:
{ type result = Int of int | Float of float | String of string }
let digit = ['0'-'9']
let digits = digit +
let lower_case = ['a'-'z']
let upper_case = ['A'-'Z']
let letter = upper_case | lower_case
let letters = letter +
rule main = parse
(digits)'.'digits as f { Float (float_of_string f) }
| digits as n { Int (int_of_string n) }
| letters as s { String s}
| _ { main lexbuf }
{ let newlexbuf = (Lexing.from_channel stdin) in
let result = main newlexbuf in
print_endline result }
我认为主要的问题是对main
的每次调用都会产生一个令牌,而在您的代码中只有对main
的一次调用。因此,它将只处理一个令牌。
您需要有某种重复调用main
的迭代。
OCamlex中有一个特殊的模式eof
,它与输入文件的末尾相匹配。您可以使用它来返回一个停止迭代的特殊值。
作为附带说明,不能使用结果作为参数来调用print_endline
。其参数必须是字符串。您需要编写自己的函数来打印结果。
更新
要获得迭代,请将代码更改为以下内容:
{
let newlexbuf = Lexing.from_channel stdin in
let rec loop () =
match main newlexbuf with
| Int i -> iprint i; loop ()
| Float f -> fprint f; loop ()
| String s -> sprint s; loop ()
| Endfile -> ()
in
loop ()
}
然后在你的模式中添加一条类似这样的规则:
| eof { Endfile }
然后添加Endfile
作为您类型的元素。
A假设这是家庭作业。因此,请确保您看到迭代是如何工作的。除了ocamllex的细节之外,这也是你想要掌握的东西(对不请自来的建议表示歉意(。