我正在尝试实现一个读取正则表达式的解析器。它要求用户输入字符串/整型/浮点数的有效输入。如果有效且用户按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 }发布于 2022-03-18 22:00:54
我要说的主要问题是,每个对main的调用都会产生一个令牌,而代码中只有一个对main的调用。因此,它将只处理一个令牌。
您需要有某种反复调用main的迭代。
在eof中有一个特殊的模式OCamllex,它与输入文件的末尾相匹配。您可以使用它返回一个停止迭代的特殊值。
作为附带注释,您不能使用结果作为参数调用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的细节之外,这是您想要掌握的东西(对于未经请求的建议表示歉意)。
https://stackoverflow.com/questions/71533397
复制相似问题