1

I'm trying to write an interpreter in OCaml and I have a problem here.

In my program, I want to call a function like this, for example:

print (get_line 4)  // print: print to stdout, get_line: get a specific line in a file

How can I do that? The problem is in our parser, I think so as it defines how a program will be run, how a function is defined and the flow of a program. This is what I have so far in parser an lexer (code below), but it didn't seem to work. I don't really see any difference between my code and the calculator on OCaml site, the statement inside the bracket is evaluated firstly, then return its value to its parent operation to do the next evaluating.

In my interpreter, the function get_line inside bracket is evaluate firstly, but I don't think it returns the value to print function, or it does but wrong type (checked, but I don't think it's this error).

One difference between calculator and my interpreter is that the calculator is working with primitive types, mine are functions. But they should be similar.

This is my code, just a part of it:

parser.mly:

%token ODD
%token CUT
%start main
%type <Path.term list> main
%%

main:
    | expr EOL main {$1 :: $3}
    | expr EOF { [$1] }
    | EOL main { $2 }
;
expr:
        | ODD INT  { Odd $2}
    | ODD LPAREN INT RPAREN  expr { Odd $3 }
        | CUT INT INT { Cut ($2, $3)}
    | CUT INT INT expr { Cut ($2, $3) }

lexer.mll:

{
    open Parser
}
(* define all keyword used in the program *)
rule main =
    parse
        | ['\n'] { EOL }
        | ['\r']['\n'] { EOL }
        | [' ''\t''\n']     { main lexbuf }     
        | '('       { LPAREN }
        | ')'       { RPAREN }
        | "cut" { CUT }     
        | "trunclength" { TRUNCLENGTH }
        | "firstArithmetic" { FIRSTARITH }
        | "f_ArithmeticLength" { F_ARITHLENGTH }
        | "secondArithmetic" { SECARITH }
        | "s_ArithmeticLength" { S_ARITHLENGTH }
        | "odd" { ODD }
        | "oddLength" { ODDLENGTH }
        | "zip" { ZIP }
        | "zipLength" { ZIPLENGTH }
        | "newline" { NEWLINE }
        | eof  { EOF }              
        | ['0' - '9']+ as lxm { INT(int_of_string lxm) }
        | ['a'-'z''A'-'Z'] ['a'-'z''A'-'Z''0'-'9']* as lxm { STRING lxm  }
Benoît Guédas
  • 801
  • 7
  • 25
Trung Bún
  • 1,117
  • 5
  • 22
  • 47

2 Answers2

0
| ODD LPAREN INT RPAREN  expr { Odd $3 }

Your grammar rule requires an INT between parenthesis. You need to change that to an expr. There are a number of other issues with this, but I'll leave it at that.

nlucaroni
  • 47,556
  • 6
  • 64
  • 86
0

First, you parser only tries to build a list of Path.term, but what do you want to do with it?

Then, there are many things wrong with your parser, so I don't really know where to start. For instance, the second and fourth case of the expr rule totally ignore the last expr. Moreover, your parser only recognize expressions containing "odd <int>" (or "odd (<int>)") and "cut <int> <int>", so how is it supposed to evaluate print and get_line? You should edit your question and try to make it clearer.

To evaluate expressions, you can

  • do it directly inside the semantic-actions (as in the calculator example),
  • or (better) build an AST (for Abstract Syntax Tree) with your parser and then interpret it.

If you want to interpret print (get_line 4), your parser need to know what print and get_line mean. In your code, your parser will see print or get_line as a STRING token (having a string value). As they seem to be keywords in your language, your lexer should recognize them and return a specific token.

Benoît Guédas
  • 801
  • 7
  • 25
  • The Path.term is defined in our interpreter so it is ok i think :) – Trung Bún Mar 19 '14 at 17:01
  • Ok, but what is it used for? And how is it related to what you want to do: "intrepret a program"? – Benoît Guédas Mar 19 '14 at 17:13
  • that file contains all function that our keywords defined in lexer will use. So when i call a keyword defined in lexer in my program, it will be parsed by the parser, and then the function corresponding to the parsed keyword (in expr .... ) will execute and give me answer. I hope this is clear. – Trung Bún Mar 19 '14 at 17:35
  • So, what do you want to do with the expr lexing rule? Can you give an example of valid input (with "odd" and "cut"), and the expected result (the contents of the Path.term list)? – Benoît Guédas Mar 19 '14 at 19:17