Question

I'm writing an interpreter, using ocamlyacc and ocamllex to compile my parser and lexer.

My problem is that, I have a file calles test, contain 2 commands that are defined in lexer:

print a
print b

but the interpreter just execute line print a only! I know the problem is in main in parser, need to be recursed. I fixed it to be like this (code below) but it still doesn't work.

%{  
    open Path
%}

%token <int> INT
%token <string> STRING
%token EOL
%token EOF
%token GET_LINE
%token PRINT

%start main
%type <Path.term> main
%%

main:
    | expr EOL  {$1}
    | expr EOF  {$1}
;


str:
    | STRING { $1 }
    ;
intger:
    | INT {$1 }
    ;
expr:

    | PRINT str  { Print $2 }
    | PRINT str expr  { Print $2 }
    | GET_LINE INT str  { Print_line_in_file ($2, $3) } 
    | GET_LINE INT str expr  { Print_line_in_file ($2, $3) }        
    ;

EDIT

this is my lexer, i tried to simplify it as much as possible to spot the error.

(* File lexer.mll *)

{
    open Parser
}

rule main = parse
    | [' ''\t''\n']     { main lexbuf }
    | "print_line_in_file" { GET_LINE }
    | "print" { PRINT}
    | ['1' - '9']+ as lxm { INT(int_of_string lxm) }
    | ['a'-'z''A'-'Z'] ['a'-'z''A'-'Z''0'-'9']* as lxm { STRING lxm  }
    | eof  {EOF}

Main.ml

open Path

let _ =
    try
    let filename = Sys.argv.(1) 
    in
        let lexbuf = Lexing.from_channel (open_in filename)
        in 
            let result = Parser.main Lexer.main lexbuf
            in
                command result;
                flush stdout
    with Parsing.Parse_error -> print_string "Error! Check syntax";
    flush stdout
Was it helpful?

Solution

To expand on gasche's answer, you need to change your parser definition as follows:

%type <Path.term list> main
%%

main:
    | expr EOL main {$1::$3}
    | expr EOF      {[$1]}
    | EOF           {[]}  /* if you want to allow a redundant EOL at the end */
;

With your original definition, a single line is considered a complete parse for main, that's why your parser stops after that.

OTHER TIPS

Each time you call the parser, it will only parse one expression (that's the type of your starting rule); and it will stop at the end of line (given how you use EOL in your grammar). You need to call it several times in a loop if you want to parse several expressions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top