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

Parsing.Parse_error

Expand Messages
  • George
    Hello, I am having troubles with the ocamlyacc. ... %start func %type func %% func: FUNC NAME ops END_FUNC { .... } ops: ops op op: PLUS {...} ...
    Message 1 of 4 , Oct 22, 2012
    • 0 Attachment
      Hello,

      I am having troubles with the ocamlyacc.
      I have an mly like this:

      ------------
      %start func
      %type < Types.f > func

      %%

      func:
      FUNC NAME ops END_FUNC { .... }

      ops:
      ops op

      op:
      PLUS {...}
      | MINUS {...}
      ------------

      That compiles without any problem but fails to parse anything.
      If I remove the 'func' word and go straight to 'ops' - parsing works perfectly.

      Are there any ways to add some verbosity to the actual parsing process in runtime? How to find why my 'func' word is not parsed properly?
    • Gabriel Scherer
      A simple and slightly stupid advice would be to instrument the lexer: each time you produce a token, print it to the error output as well, so that you get an
      Message 2 of 4 , Oct 23, 2012
      • 0 Attachment
        A simple and slightly stupid advice would be to instrument the lexer:
        each time you produce a token, print it to the error output as well,
        so that you get an idea of what the parser is fed.

        I would strongly recommend that you consider using menhir instead of
        ocamlyacc. It allows more readable grammars and provides more
        features, in particular debugging features that are indeed very
        useful.
        http://gallium.inria.fr/~fpottier/menhir/

        On Mon, Oct 22, 2012 at 9:45 PM, George <siberianowl@...> wrote:
        > Hello,
        >
        > I am having troubles with the ocamlyacc.
        > I have an mly like this:
        >
        > ------------
        > %start func
        > %type < Types.f > func
        >
        > %%
        >
        > func:
        > FUNC NAME ops END_FUNC { .... }
        >
        > ops:
        > ops op
        >
        > op:
        > PLUS {...}
        > | MINUS {...}
        > ------------
        >
        > That compiles without any problem but fails to parse anything.
        > If I remove the 'func' word and go straight to 'ops' - parsing works perfectly.
        >
        > Are there any ways to add some verbosity to the actual parsing process in runtime? How to find why my 'func' word is not parsed properly?
        >
        >
        >
        > ------------------------------------
        >
        > Archives up to December 31, 2011 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
        > The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
        > Attachments are banned and you're asked to be polite, avoid flames etc.Yahoo! Groups Links
        >
        >
        >
      • Virgile Prevosto
        Hello, Le lun. 22 oct. 2012 19:45:02 CEST, ... You might want to have a look in Sec. 12.5 of the manual
        Message 3 of 4 , Oct 23, 2012
        • 0 Attachment
          Hello,

          Le lun. 22 oct. 2012 19:45:02 CEST,
          "George" <siberianowl@...> a écrit :

          >
          > Are there any ways to add some verbosity to the actual parsing
          > process in runtime? How to find why my 'func' word is not parsed
          > properly?
          >

          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.

          Best regards,
          --
          E tutto per oggi, a la prossima volta.
          Virgile
        • George
          ... 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
          Message 4 of 4 , Oct 23, 2012
          • 0 Attachment
            --- 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?
          Your message has been successfully submitted and would be delivered to recipients shortly.