Loading ...
Sorry, an error occurred while loading the content.

13640Re: "ocaml_beginners"::[] Parsing.Parse_error

Expand Messages
  • George
    Oct 23, 2012
      --- In ocaml_beginners@yahoogroups.com, Virgile Prevosto <virgile.prevosto@...> wrote:
      >
      > You might want to have a look in Sec. 12.5 of the manual
      > (http://caml.inria.fr/pub/docs/manual-ocaml/manual026.html)
      > Basically, ocamlyacc -v parser.mly will give you a description of the
      > resulting automaton in parser.output. Then, running your
      > executable with OCAMLRUNPARAM=p will print all the actions of the parser
      > (shift and reduce) on stdout.

      Thank you,

      It looks promising, but unfortunately I do not understand how to read the automata it generated.
      Here is a simple project:

      -- parser.mly
      %token ONE TWO
      %token EOF
      %start ops
      %type <int list> ops
      %%
      ops: {[]}
      | ops op {$2 :: $1}
      op: ONE {1}
      | TWO {2}
      ---------------

      -- scanner.mll
      {open Parser;;}
      rule token = parse
      [' ' '\t' '\r' '\n'] { token lexbuf }
      | '1' { ONE }
      | '2' { TWO }
      | eof { EOF }
      ---------------

      -- main.ml
      open Scanner;;
      let _ =
      let lexbuf = Lexing.from_channel stdin in
      let l = Parser.ops Scanner.token lexbuf in
      List.iter (fun x -> print_int x; print_char ' ') (List.rev l);
      print_newline();;
      ---------------

      -- runit.sh
      ocamlyacc -v parser.mly
      ocamlc -warn-error A -c parser.mli
      ocamlc -warn-error A -c parser.ml
      ocamllex scanner.mll
      ocamlc -warn-error A -c scanner.ml
      ocamlc -warn-error A -c main.ml
      ocamlc -o one_two_parser parser.cmo scanner.cmo main.cmo
      export OCAMLRUNPARAM='p' && ./one_two_parser <in >out 2>err
      ---------------

      The resulting parser.output:
      ---------------
      0 $accept : %entry% $end

      1 ops :
      2 | ops op

      3 op : ONE
      4 | TWO

      5 %entry% : '\001' ops

      state 0
      $accept : . %entry% $end (0)

      '\001' shift 1
      . error

      %entry% goto 2


      state 1
      %entry% : '\001' . ops (5)
      ops : . (1)

      . reduce 1

      ops goto 3


      state 2
      $accept : %entry% . $end (0)

      $end accept


      state 3
      ops : ops . op (2)
      %entry% : '\001' ops . (5)

      ONE shift 4
      TWO shift 5
      $end reduce 5

      op goto 6


      state 4
      op : ONE . (3)

      . reduce 3


      state 5
      op : TWO . (4)

      . reduce 4


      state 6
      ops : ops op . (2)

      . reduce 2


      6 terminals, 4 nonterminals
      6 grammar rules, 7 states
      -------------------------------

      And if I run this project on a file which contains string "1 2 2 1" I receive a list of actions:
      --------------------------------
      State 0: shift to state 1
      State 1: reduce by rule 1
      State 3: read token ONE
      State 3: shift to state 4
      State 4: reduce by rule 3
      State 6: reduce by rule 2 ??? Why state 6?
      State 3: read token TWO
      State 3: shift to state 5
      State 5: reduce by rule 4
      State 6: reduce by rule 2
      State 3: read token TWO
      State 3: shift to state 5
      State 5: reduce by rule 4
      State 6: reduce by rule 2
      State 3: read token ONE
      State 3: shift to state 4
      State 4: reduce by rule 3
      State 6: reduce by rule 2
      State 3: read token EOF
      State 3: reduce by rule 5
      --------------------------------

      Why ocamlyacc reported 6 terminals? I defined only two tokens ONE and TWO, where did other 4 come from?
      Same with nonterminals, I see ops and op - just two. Why ocamlyacc sees 4???

      What do '\001', point and %entry% mean?
      What rules 0 and 5 mean? Why they were created?
      Are there any meaning in empty lines in the state definitions?

      Are there any comprehensive and full documentation on the ocamlyacc?
    • Show all 4 messages in this topic