How to scan with ocamllex until end of file

298 views Asked by At

I am trying to implement a parser that read regular expression. It ask the user to enter a valid input of string/integers/float. If is valid and the user press ctrl^d, then print the number. Otherwise shows an error. But the problem in the following code does not stop when I press ctrl^D. How to implement eof token and print the input ?

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 }
1

There are 1 answers

1
Jeffrey Scofield On

I'd say the main problem is that each call to main produces one token, and there's only one call to main in your code. So it will process just one token.

You need to have some kind of iteration that calls main repeatedly.

There is a special pattern eof in OCamllex that matches the end of the input file. You can use this to return a special value that stops the iteration.

As a side comment, you can't call print_endline with a result as its parameter. Its parameter must be a string. You will need to write your own function for printing the results.

Update

To get an iteration, change your code to something like this:

{
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 ()
}

Then add a rule something like this to your patterns:

| eof { Endfile }

Then add Endfile as an element of your type.

A assume this is homework. So make sure you see how the iteration is working. Aside from the details of ocamllex, that's something you want to master (apologies for unsolicited advice).