0

Мне было интересно, как написать три адресных кода с помощью ocamllex и ocamlyacc? Я много искал об этом, но ничего не нашел, используя ocamlyacc. У меня есть мой парсер и мой лексер, работающий (оба, конечно, ocamlyacc и ocamllex), но теперь я должен написать три генератора кода адреса, используя их. Например, предположим, что у меня этот парсер (калькулятор):Как написать три адресных кода с помощью ocamllex и ocamlyacc?

Как написать три кода адреса?

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

Пример:

ВХОД:

5+ (5 * 7)

Три Адрес кода Выход:

t1 = 5 * 7

t2 = 5 + t1

+0

Знаете ли вы, как выглядит ответ на конкретный вход? Начните с этого и посмотрите, можете ли вы определить алгоритм его генерации. –

+0

он хотел бы получить нормальный три кода addres, например, если я вхожу с: 5+ (8 * 8), три кода addres в stdout должны быть: 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 } 
; 

 Смежные вопросы

  • Нет связанных вопросов^_^