0

I was wondering how to write a three address code using ocamllex and ocamlyacc? I googled a lot about this, but I couldn't find anything using ocamlyacc. I have my parser and my lexer working(both using of course ocamlyacc and ocamllex) but now I have to write a three address code generator using them. For example, suppose that I have this parser(Calculator):

How should I write the three address code?

Parser:

input: /* empty */ { }
    | input line { }
;

line: NEWLINE { }
    | exp NEWLINE { }

;

exp: NUM { }
    | exp PLUS exp  { }
    | exp MINUS exp { }
    | exp MULTIPLY exp { }
    | exp DIVIDE exp { }
    | MINUS exp %prec NEG { }

    | exp CARET exp { }

    | LPAREN exp RPAREN { }
;

Example:

INPUT:

5+(5*7)

Three Address Code Output:

t1 = 5*7

t2 = 5+t1

Benoît Guédas
  • 801
  • 7
  • 25
tsukanomon
  • 1,220
  • 1
  • 19
  • 23
  • Do you know what the answer looks like for a specific input? Start with that, and see if you can define an algorithm to generate it. – Ira Baxter May 01 '12 at 23:13
  • it would like a normal three addres code output,for example if I enter with: 5+(8*8) the three addres code in stdout should be: t1 = 8*8; t2 = 5+t1; – tsukanomon May 03 '12 at 01:13
  • Its easier this way: t1=8; t2 = t1*t1; t3=5; t4 = t2+t3; OK so, how are you going to generate it? – Ira Baxter May 03 '12 at 03:22
  • The problem is, I dont know how to generate it using, ocamlyacc.. – tsukanomon May 03 '12 at 11:57
  • I'm unclear on what you don't know: how to generate 3 address code in general, how to code in ocaml, or how to use ocamlyacc. The usual cure for each of these is to go do some reading so you understand that aspect of the problem better. And you're not going to get a lot of help until you can describe explicitly the problem you're having. – Ira Baxter May 03 '12 at 13:56
  • Ok, my problem is how to implement in ocaml using the ocamlyacc, the three address code, output. – tsukanomon May 05 '12 at 05:55
  • That isn't a helpful description. What specific thing have you tried? – Ira Baxter May 05 '12 at 06:26

1 Answers1

2

Here is a solution:

You first have to add this in the header of your mly file:

%{  
  let count = ref 0

  let tn () = "t" ^ (string_of_int !count)

  let print_operation op x1 x2 =
    incr count;
    print_endline ((tn ()) ^ " = "^ x1 ^ op ^ x2)
%}

then, your rules will look like (I removed the second rule, and the unary minus to simplify):

input: EOF {}
    | exp NEWLINE input { }
;

exp: NUM { $1 }
    | exp PLUS exp  { print_operation " + "$1 $3; tn () }
    | exp MINUS exp { print_operation " - " $1 $3; tn () }
    | exp MULTIPLY exp { print_operation " * " $1 $3; tn () }
    | exp DIVIDE exp { print_operation " / " $1 $3; tn () }
    | exp CARET exp { print_operation " ^ " $1 $3; tn () }
    | LPAREN exp RPAREN { $2 }
;
Benoît Guédas
  • 801
  • 7
  • 25