This is an old revision of the document!
Dans le domaine informatique, le code de trois adresses (three address code) représente un code intermédiaire utilisé pour les compilateurs en tant que moyen d'écrire des instructions. Chaque instruction consiste en:
Contrairement au TP précédent où la transformation a été implémentée a l'aide des variables temporaires, l'objectif de ce travail est de représenter le Three Address Code
en simulant une pile.
Ws [ \t] Number [0-9]+("."[0-9]+)? String_value \"[^\"]*\" Identifier [A-Za-z][A-Za-z0-9]* Newline \r?\n %% "def" { return 'DEF'; } "int" { return 'INT'; } "float" { return 'FLOAT'; } "string" { return 'STRING'; } "function" { return 'FUNCTION'; } "end" { return 'END'; } "=" { return '='; } "-" { return '-'; } "+" { return '+'; } "*" { return '*'; } "/" { return '/'; } "(" { return 'LP'; } ")" { return 'RP'; } ',' { return ','; } {Ws} { /*skip whitespace*/ } {Newline} { return 'NEWLINE'; } {Number} { return 'NUMBER'; } {String_value} { return 'STRING_VALUE'; } {Identifier} { return 'IDENTIFIER'; }
%left '+' '-' // * and / have higher priority %left '*' '/' %% %left '+' '-' // * and / have higher priority %left '*' '/' %% start: statements { $$ = { type:'module', statements: $1 }; return $$; }; statements : statement NEWLINE statements { $3.splice (0, 0, $1); $$ = $3; } | statement NEWLINE { $$ = [$1]; } | statement { $$ = [$1]; } ; statement : expression {} | assign {} | function_call {} ; expression : LP expression RP { $$ = $2; } | expression '+' expression { $$ = { type: 'expression', operator: '+', left: $1, right: $3 }; } | expression '-' expression { $$ = { type: 'expression', operator: '-', left: $1, right: $3 }; } | expression '*' expression { $$ = { type: 'expression', operator: '*', left: $1, right: $3 }; } | expression '/' expression { $$ = { type: 'expression', operator: '/', left: $1, right: $3 }; } | IDENTIFIER { $$ = { type: 'identifier', value: $1 }; } | NUMBER { $$ = { type: 'number', value: parseFloat ($1) }; } | STRING_VALUE { $$ = { type: 'string', value: $1.substring (1, $1.length-2) }; } ; assign : IDENTIFIER '=' expression { $$ = { type: 'assign', to: $1, from: $3 }; } | IDENTIFIER '=' function_call { $$ = { type: 'assign', to: $1, from: $3 }; } ; function_call : IDENTIFIER LP parameters_run RP { $$ = { type: 'function_call', function: $1, parameters: $3 }; }; parameters_run : expression ',' parameters_run { $3.splice (0, 0, $1); $$ = $3; } | expression { $$ = [$1]; } | { $$ = []; } ;
"use strict"; // import fs for reading var fs = require ('fs'); // import the generated Parser var parser = require ('./alf.js').parser; var str = fs.readFileSync (process.argv[2], 'UTF-8'); var variable_id = 0; // get a new temporary variable function nextVar () { return 'var' + variable_id++; } function writeThreeAddressCode (node) { if (node.type === 'module') { for (var statement of node.statements) { writeThreeAddressCode(statement); } } else if (node.type === 'function_call') { } else if (node.type === 'number') { } else if (node.type === 'assign') { } else if (node.type === 'identifier') { } else if (node.type === 'expression') { if (node.left !== undefined && node.right !== undefined) { } } } var ast = parser.parse (str); console.log (JSON.stringify(ast, null, 4)); writeThreeAddressCode(ast);
if (a > 0) { result = 'positive'; } else { result = 'negative'; }
function double (nr) { return nr*2; } double (7/2);
2 + 3 / double(a)
). Testez la validité de la grammaire avec le fichier ex5.txt et vérifiez que le programme ne retourne aucune erreur. (1p)function function_name(param1, param2, ...) { statement1 statement2 ... }
Suivez les lignes marquées par TODO8 afin de générer le Three Address Code pour les fonctions. (2p)