Trung Bún
Trung Bún

Reputation: 1147

OCaml Interpreter: Why my interpreter just execute only one line in my file

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

Upvotes: 0

Views: 338

Answers (2)

Andreas Rossberg
Andreas Rossberg

Reputation: 36118

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.

Upvotes: 2

gasche
gasche

Reputation: 31469

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.

Upvotes: 2

Related Questions