0

我想知道如何使用ocamllex和ocamlyacc編寫三個地址代碼? 我搜索了很多關於這個,但我無法找到任何使用ocamlyacc。 我有我的解析器和我的詞法分析器工作(都使用ocamlyacc和ocamllex),但現在我必須寫一個三地址碼發生器使用它們。 例如,假設我有這個解析器(計算器):如何使用ocamllex和ocamlyacc編寫三個地址代碼?

我應該如何編寫這三個地址代碼?

分析器:

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

+0

你知道某個具體輸入的答案是什麼嗎?從那開始,看看你是否可以定義一個算法來生成它。 –

+0

它會想要一個正常的三個地址碼輸出,例如,如果我輸入:5+(8 * 8)標準輸出中的三個地址碼應該是: t1 = 8 * 8; t2 = 5 + t1; – tsukanomon

+0

這樣更簡單:t1 = 8; t2 = t1 * t1; T3 = 5; t4 = t2 + t3;好的,那你怎麼生成它? –

回答

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