如何使用ocamllex和ocamlyacc编写三个地址代码?

时间:2012-05-01 21:25:19

标签: optimization compiler-construction ocaml ocamlyacc ocamllex

我想知道如何使用ocamllex和ocamlyacc编写三个地址代码? 我搜索了很多关于这一点,但我找不到任何使用ocamlyacc的东西。 我有我的解析器和我的词法分析器工作(当然使用ocamlyacc和ocamllex)但现在我必须使用它们编写一个三地址代码生成器。 例如,假设我有这个解析器(Calculator):

我该如何写三个地址代码?

分析器:

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 { }
;

示例:

INPUT:

5+(5 * 7)

三个地址代码输出:

t1 = 5 * 7

t2 = 5 + t1

1 个答案:

答案 0 :(得分:2)

这是一个解决方案:

首先必须在你的mly文件的标题中添加它:

%{  
  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)
%}

然后,你的规则看起来像(我删除了第二条规则,并且一元减去简化):

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 }
;