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.
/* Expression */ (5-3)*7; /* Three Address Code */ push 5 push 3 sub push 7 mul
grammar Alf; start : (statement SEMICOLON NEWLINE*)* #multilineProg | statement SEMICOLON #singlelineProg ; statement : declaration #declarationRule | expression #expressionRule | list_declaration #listRule | function_declaration #functionRule | attribution #attributionRule | function_call #functionCallRule ; declaration : type VARIABLE EQ expression #variableDeclaration | type VARIABLE EQ function_call #variableFunctionCall ; type : INT #typeInt | FLOAT #typeFloat | STRING #typeString ; value : INT_NUMBER #valueInt | FLOAT_NUMBER #valueFloat | STRING_TEXT #valueString | VARIABLE #valueVariable ; expression : left=expression op=MUL right=expression #expressionMultiply | left=expression op=DIV right=expression #expressionDivision | left=expression op=REM right=expression #expressionRem | left=expression op=ADD right=expression #expressionAddition | left=expression op=SUB right=expression #expressionSubtraction | LP expression RP #expressionParanthesis | value #expressionValue ; attribution : VARIABLE EQ expression #variableAttribution ; list_declaration : LIST VARIABLE EQ LSP values RSP #listDeclaration ; values : (value COMMA)* #listValues ; function_declaration: FUNCTION VARIABLE LP (parameter COMMA*)* RP LB (statement SEMICOLON)* return_function RB #functionContent ; parameter : declaration #functionParameter ; return_function : RETURN statement SEMICOLON #returnStatement | RETURN SEMICOLON #emptyReturn ; function_call : VARIABLE LP (value COMMA*)* RP #functionCall ; WS : (' ') -> skip; NEWLINE : ([\r\n]+) -> skip; FUNCTION : 'function'; VARIABLE : ('_'[a-zA-Z0-9]+); ADD : '+'; SUB : '-'; MUL : '*'; DIV : '/'; REM : '%'; INT : 'int'; FLOAT : 'float'; STRING : 'string'; LIST : 'list'; LP : '('; RP : ')'; EQ : '='; SEMICOLON : ';'; LSP : '['; RSP : ']'; COMMA : ','; LB : '{'; RB : '}'; RETURN : 'return'; INT_NUMBER : ([0-9]+); FLOAT_NUMBER : ([0-9]+'.'[0-9]+); STRING_TEXT : ('"'~["]+'"'|'\''~[']+'\''); ;
import { ASTNode } from "./index"; import symbol_tree from './index'; import { Expression, ValueNode, AttributionNode, FunctionCallNode } from './index'; var variable_id = 0; let results: string[] = []; function nextVar () { return 'var' + variable_id++; } function writeThreeAddressCode (node) { if (node.id === 'StatementsNode') { for (var statement of node.statements) { writeThreeAddressCode(statement); } } else if (node instanceof FunctionCallNode) { } else if (node instanceof ValueNode) { } else if (node instanceof VariableNode) { } else if (node instanceof AttributionNode) { } else if (node instanceof 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. (1p)