4

I have implemented this example, and it works well.

Now, I want to read from a string instead of reading from stdin, so I change the calc.ml:

let _ =
  try
    let lexbuf = Lexing.from_string "1+3" in
    let result = Parser.main Lexer.token lexbuf in
    print_int result
  with Lexer.Eof ->
    print_string "Lexer.Eof";
    exit 0

And oddly, it returns Lexer.Eof as result. If I remove | eof { raise Eof } from lexer.mll and , it tells Fatal error: exception Failure("lexing: empty token"). I guess something is wrong around end-of-input condition... Does anyone know how to change the lexer so that it could lex a string?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
SoftTimur
  • 5,630
  • 38
  • 140
  • 292

1 Answers1

4

You forgot the EOL:

let _ =
  try
    let lexbuf = Lexing.from_string "1+3\n" in
    let result = Parser.main Lexer.token lexbuf in
    print_int result
  with Lexer.Eof ->
    print_string "Lexer.Eof";
    exit 0

EDIT

Or if you do not want to add the EOL:

In parser.mly, add the token EOF and:

| expr EOF                    { $1 }

In lexer.mll, not raise eof but return the token EOF:

| eof            { EOF }

And finally, calc.ml:

let _ =
    let lexbuf = Lexing.from_string "3+1" in
    let result = Parser.main Lexer.token lexbuf in
    print_int result
Çağdaş Bozman
  • 2,537
  • 16
  • 21
  • Thanks, that does work. But I want to parse a normal sting without EOL. I have changed to `main: expr { $1 };` in `parser.mly`, oddly with `"1+3"` it still returns `Lexer.Eof`, does `Lexing.from_string` accepts only string ending by `"\n"`? – SoftTimur Dec 21 '12 at 14:54