Autor Tópico: Cross-Compiler - Código de um compilador  (Lida 1298 vezes)

Offline KTachyon

  • Global Moderator
  • Newbie
  • *****
  • Mensagens: 0
  • Karma: +0/-0
    • Ver Perfil
    • http://twitter.com/KTachyon
Cross-Compiler - Código de um compilador
« em: Junho 18, 2006, 05:49:51 am »
Para algumas (ou uma) pessoa que não acredita que neste forum à pessoas capazes de criar um compilador, aqui vai o código (separado em posts por cada secção do ficheiro com a explicação do que faz cada um no início do post):

Enunciado:

Citar
A linguagem LYSP (Lex and Yacc very Simple lisP­like language) consiste num muito pequeno subconjunto de funcionalidades inspiradas na linguagem Lisp. Existem apenas três comandos:

– defun – sintaxe exactamente como na linguagem Lisp (defun <nome da função>
(argumentos) <corpo da função>), serve para definir uma função que poderá a partir daí ser utilizada por outras funções. Por exemplo, podemos definir a função “sum”, que recebe dois argumentos (X e Y) e os soma:

(defun sum (X Y)
 (+ X Y))

– if – sintaxe exactamente como na linguagem Lisp (if <condição> <corpo do then> [<corpo do else>]), é uma instrução de selecção. Caso a condição seja verdadeira, executa o corpo do then, caso contrário, executa o corpo do else, se este existir. Por exemplo, se quisermos fazer uma divisão de X por Y apenas se Y for diferente de 0 (se for igual a zero, devolver -9999999):

(if (= Y 0)
 ­9999999
 (/ X Y))

– deflocal – comando para criar uma variável. A sintaxe será ( deflocal <lista
de pares identificador/valor>). O def local terá um scope correspondente ao nível em que está inserido, ou a subníveis em que é chamado (ou seja, se for dentro de uma função, será “visível” apenas dentro dela; se for no toplevel, acaba por ser uma variável global). Se quisermos definir 3 variáveis (X, Y e Z), atribuindo­lhes os valores de inicialização (0, 1 e ­1, respectivamente):
 
(deflocal X 0 Y 1 Z ­1)

Nesta linguagem, existe um e um só tipo de variável: inteiro. Ou seja, não existem valores reais nem strings (ou até mesmo listas). Como tal, é uma linguagem funcional:

cada função devolve um e um só valor; não existe qualquer comando de ciclo ( for, do ou while) portanto as repetições terão que ser baseadas em chamadas recursivas às funções;

todos os comandos são, em última análise, funções. Por exemplo, um comando defun deverá devolver 0, um comando if deverá devolver o resultado da chamada a then ou else (0, caso não haja parte else e a condição for falsa), e o comando deflocal deverá devolver o último valor atribuído.

Para além destes comandos, existem também as operações aritméticas básicas (+, ­, /, *), que podem ser aplicadas a listas de números/variáveis:

(+ 2 3 4 5) ­­> devolve 2+3+4+5=14
(­ 2 3 4 5) ­­> devolve 2­3­4­5=­10
(/ 2 3 4 5) ­­> devolve 2/3/4/5=0 (divisão inteira)
(* 2 3 4 5) ­­> devolve 2*3*4*5=120

Existem também os operadores de comparação básicos (=, <, >, <=, >=), que podem ser aplicados a pares de funções:

(> 1 0) ­­> devolve 1
(< 1 0) ­­> devolve 0

Assim, poderá fazer composição destes comandos e operadores para fazer funções de alguma complexidade. Por exemplo, a função abaixo calcula o factorial de um número.

(defun factorial (n)
 (if (= n 0)
 1
 (* n (factorial (­ n 1)))))

Um programa em LYSP consistirá numa sequência de chamadas executadas no toplevel, ou seja o programa deverá executar o primeiro comando, depois o segundo, depois o terceiro e assim sucessivamente. Cada uma destas execuções deverá resultar na impressão para o output do valor obtido. Por exemplo, um pequeno programa para calcular o factorial de 9, 6 e 3:

(defun factorial (n)
 (if (= n 0)
 1
 (* n (factorial (­ n 1)))))
(factorial 9)
(factorial 6)
(factorial 3)

Ao correr este programa, o output gerado seria:
0
362880
720
6

O facto de as execuções serem feitas em sequência implica que uma variável (ou uma função) não pode ser utilizada antes de ser declarada. Por exemplo,

(+ x 8)
(deflocal x 0)

A variável “x” não é conhecida quando é feita a soma. Teria que ser ao contrário:
(deflocal x 0)
(+ x 8)

O resultado seria então
0
8
My Q4 estimate: Macs: 5.89M; iPods: 4.19M; iPhones: 30.0M; iPads: 18.05M; Revenue: 37.00B; EPS: 9.50
AAPL Q3 result: Macs: 4.02M; iPods: 6.80M; iPhones: 26.0M; iPads: 17.04M; Revenue: 35.02B; EPS: 9.32

Offline KTachyon

  • Global Moderator
  • Newbie
  • *****
  • Mensagens: 0
  • Karma: +0/-0
    • Ver Perfil
    • http://twitter.com/KTachyon
Cross-Compiler - Código de um compilador
« Responder #1 em: Junho 18, 2006, 05:54:25 am »
Código Lex:

Realiza a análise lexical (identificação dos tokens e o seu envio para o Yacc com a label correspondente).


LYSP.l

Código: [Seleccione]

%{

#include "structures.h"

#include "y.tab.h"

#include <stdlib.h>

#include <string.h>



void lowercase(char string[]);

%}



%%

";".*n {line++;}



"-"?[0-9]+ {yylval.value = atoi(yytext); return NUMBER;}



"if" {return IF;}

"defun" {return DEFUN;}

"deflocal" {return DEFLOCAL;}



"and" {return AND;}

"or" {return OR;}

"not" {return NOT;}

"xor" {return XOR;}



"<=" {return MENOR_EQ;}

">=" {return MAIOR_EQ;}





[a-zA-Z][a-zA-Z0-9_]* {lowercase(yytext); yylval.var = (char*) strdup(yytext); return VAR;}



[ t] ;



n {line++;}



. return yytext[0];

%%

int yywrap()

{

return 1;

}



void lowercase(char string[])

{

int  i;



for (i = 0; string[i]; i++)

string[i] = tolower(string[i]);

}
My Q4 estimate: Macs: 5.89M; iPods: 4.19M; iPhones: 30.0M; iPads: 18.05M; Revenue: 37.00B; EPS: 9.50
AAPL Q3 result: Macs: 4.02M; iPods: 6.80M; iPhones: 26.0M; iPads: 17.04M; Revenue: 35.02B; EPS: 9.32

Offline KTachyon

  • Global Moderator
  • Newbie
  • *****
  • Mensagens: 0
  • Karma: +0/-0
    • Ver Perfil
    • http://twitter.com/KTachyon
Cross-Compiler - Código de um compilador
« Responder #2 em: Junho 18, 2006, 05:57:34 am »
Código Yacc:

Realiza a análise sintática (verifica se os tokens estão bem posicionados na sintáxe, caso contrário dá erro de sintaxe - o código foi mal construido, logo não é aceite).


LYSP.y:

Código: [Seleccione]

%{

#include <stdio.h>

#include <stdlib.h>

#include "structures.h"

#include "functions.h"

#include "symbol_table.h"

#include "semantic.h"

#include "translation.h"



//table_element *table;



is_statement *myprogram;



//table_element *search_el(char *str);

//table_element *insert_el(char *str);



%}

%token <value> NUMBER

%token <var> VAR



%token IF

%token DEFUN

%token DEFLOCAL



%token AND

%token OR

%token XOR

%token NOT



%token MAIOR_EQ

%token MENOR_EQ



%union{

int value;

char *var;

is_statement *statement;

is_function *function;

is_single_exp *single_exp;

is_function_not *function_not;

is_arg_list *args;

is_function_defun *function_defun;

is_deflocal *deflocal;

is_function_deflocal *expressiondef;

is_function_if_comp *function_if_comp;

is_function_if_simp *function_if_simp;

is_single_exp_list *expression;

is_function_user *function_user;

is_function_op *function_op;

}



%type <statement> statement

%type <function> function

%type <function_op> function_op

%type <expressiondef> function_deflocal

%type <expressiondef> expressiondef

%type <function_defun> function_defun

%type <function_if_comp> function_if_comp

%type <function_if_simp> function_if_simp

%type <function_user> function_user

%type <function_not> function_not

%type <expression> expression

%type <single_exp> single_exp

%type <args> args

%type <deflocal> deflocal



%%



statement: single_exp {$$ = insert_statement($1, NULL); myprogram = $$;}

| statement single_exp {$$ = insert_statement($2, $1);}

;



function: function_op {$$ = insert_op_function($1);}

| function_deflocal {$$ = insert_deflocal_function($1);}

| function_defun {$$ = insert_defun_function($1);}

| function_if_simp {$$ = insert_if_simp_function($1);}

| function_if_comp {$$ = insert_if_comp_function($1);}

| function_user {$$ = insert_user_function($1);}

| function_not {$$ = insert_not_function($1);}

;



function_op: \\'(\\' \\'+\\' expression single_exp \\')\\' {$$ = insert_function_op(is_SOMA, $3, $4);}

  | \\'(\\' \\'-\\' expression single_exp \\')\\' {$$ = insert_function_op(is_SUB, $3, $4);}

  | \\'(\\' \\'*\\' expression single_exp \\')\\' {$$ = insert_function_op(is_MULT, $3, $4);}

  | \\'(\\' \\'/\\' expression single_exp \\')\\' {$$ = insert_function_op(is_DIV, $3, $4);}

  | \\'(\\' \\'<\\' expression single_exp \\')\\' {$$ = insert_function_op(is_MENOR, $3, $4);}

  | \\'(\\' \\'>\\' expression single_exp \\')\\' {$$ = insert_function_op(is_MAIOR, $3, $4);}

  | \\'(\\' MENOR_EQ expression single_exp \\')\\' {$$ = insert_function_op(is_MENOR_IGUAL, $3, $4);}

  | \\'(\\' MAIOR_EQ expression single_exp \\')\\' {$$ = insert_function_op(is_MAIOR_IGUAL, $3, $4);}

  | \\'(\\' \\'=\\' expression single_exp \\')\\' {$$ = insert_function_op(is_IGUAL, $3, $4);}

  | \\'(\\' AND expression single_exp \\')\\' {$$ = insert_function_op(is_AND, $3, $4);}

  | \\'(\\' OR expression single_exp \\')\\' {$$ = insert_function_op(is_OR, $3, $4);}

  | \\'(\\' XOR expression single_exp \\')\\' {$$ = insert_function_op(is_XOR, $3, $4);}

 ;

 

function_defun: \\'(\\' DEFUN VAR \\'(\\' args \\')\\' expression \\')\\' {$$ = insert_function_defun(line, $3, $5, $7);}

 | \\'(\\' DEFUN VAR \\'(\\' \\')\\' expression \\')\\' {$$ = insert_function_defun(line, $3, NULL, $6);}

;



function_deflocal: \\'(\\' DEFLOCAL expressiondef \\')\\' {$$ = $3;}

;

 

function_if_simp: \\'(\\' IF single_exp single_exp \\')\\' {$$ = insert_function_if_simp($3, $4);}

;



function_if_comp: \\'(\\' IF single_exp single_exp single_exp \\')\\' {$$ = insert_function_if_comp($3, $4, $5);}

;



function_user: \\'(\\' VAR expression \\')\\' {$$ = insert_function_user(line, $2, $3);}

| \\'(\\' VAR \\')\\' {$$ = insert_function_user(line, $2, NULL);}

;

 

function_not: \\'(\\' NOT function \\')\\' {$$ = insert_not_function_exp($3);}

| \\'(\\' NOT NUMBER \\')\\' {$$ = insert_not_number_exp($3);}

| \\'(\\' NOT VAR \\')\\' {$$ = insert_not_var_exp(line, $3);}

;



expression: expression single_exp {$$ = insert_single_exp_list($2, $1);}

 | single_exp {$$ = insert_single_exp_list($1, NULL);}

;

 

single_exp: function {$$ = insert_function_exp($1);}

 | NUMBER {$$ = insert_number_exp($1);}

 | VAR {$$ = insert_var_exp(line, $1);}

;



expressiondef: expressiondef deflocal {$$ = insert_function_deflocal($2, $1);}

| deflocal {$$ = insert_function_deflocal($1, NULL);}

;



deflocal: VAR single_exp {$$ = insert_deflocal($1, $2, line);}

;

 

args: args VAR {$$ = insert_arg_list(line, $2, $1);}

| VAR {$$ = insert_arg_list(line, $1, NULL);}

;





%%

int main()

{

int parsingOK;

line = 1;

successful_semantic = 1;



parsingOK = yyparse();



if (!parsingOK)

{

prog_env *pe = semantic_analysis(myprogram);



if (successful_semantic)

translate(myprogram, pe);

}

}



void yyerror (char *s)

{

printf("%s - line: %dn", s, line);

}
My Q4 estimate: Macs: 5.89M; iPods: 4.19M; iPhones: 30.0M; iPads: 18.05M; Revenue: 37.00B; EPS: 9.50
AAPL Q3 result: Macs: 4.02M; iPods: 6.80M; iPhones: 26.0M; iPads: 17.04M; Revenue: 35.02B; EPS: 9.32

Offline KTachyon

  • Global Moderator
  • Newbie
  • *****
  • Mensagens: 0
  • Karma: +0/-0
    • Ver Perfil
    • http://twitter.com/KTachyon
Cross-Compiler - Código de um compilador
« Responder #3 em: Junho 18, 2006, 06:00:18 am »
Inserts:

Código que constroi a árvore de sintaxe abstracta (consoante as chamadas do Yacc a este código).

structures.h:

Código: [Seleccione]

#ifndef _STRUCTURES_

#define _STRUCTURES_



int line;

int successful_semantic;



typedef struct _e1 is_single_exp;

typedef struct _e2 is_function;

typedef struct _a1 is_function_not;

typedef struct _a2 is_arg_list;

typedef struct _a3 is_function_defun;

typedef struct _a4 is_deflocal;

typedef struct _a5 is_function_deflocal;

typedef struct _a6 is_function_if_comp;

typedef struct _a7 is_function_if_simp;

typedef struct _a8 is_single_exp_list;

typedef struct _a9 is_function_user;

typedef struct _a10 is_function_op;

typedef struct _a11 is_statement;



typedef enum {is_SOMA, is_SUB, is_MULT, is_DIV, is_MENOR, is_MAIOR, is_MENOR_IGUAL, is_MAIOR_IGUAL, is_IGUAL, is_AND, is_OR, is_XOR} is_op;

typedef enum {d_function, d_NUMBER, d_VAR} disc_single_exp;



struct _e1 {

disc_single_exp disc_se;

union {

is_function *function;

int number;

char *var;

} data_exp;

int codeline;

};



typedef enum {d_function_op, d_function_deflocal, d_function_defun, d_function_if_simp, d_function_if_comp, d_function_user, d_function_not} disc_function;



struct _e2 {

disc_function disc_f;

union {

is_function_op *op;

is_function_deflocal *deflocal;

is_function_defun *defun;

is_function_if_simp *if_simp;

is_function_if_comp *if_comp;

is_function_user *user;

is_function_not *not;

} data_exp;

};



/*typedef enum {d_not_function, d_not_NUMBER, d_not_VAR} disc_function_not;*/



struct _a1 {

disc_single_exp disc_fn;

union {

is_function *function;

int number;

char *var;

} data_exp;

int codeline;

};



struct _a2 {

char *arg;

int codeline;

struct _a2 *next;

};



struct _a3 {

char *var;

int codeline;

is_arg_list *args;

is_single_exp_list *exp;

};



struct _a4 {

char *var;

is_single_exp *exp;

int codeline;

};



struct _a5 {

is_deflocal *def;

struct _a5 *next;

};



struct _a6 {

is_single_exp *test;

is_single_exp *return_true;

is_single_exp *return_false;

};



struct _a7 {

is_single_exp *test;

is_single_exp *return_true;

};



struct _a8 {

is_single_exp *exp;

struct _a8 *next;

};



struct _a9 {

char *var;

int codeline;

is_single_exp_list *exp;

};



struct _a10 {

is_op op;

is_single_exp_list *exp;

is_single_exp *exp_;

};



struct _a11 {

is_single_exp *exp;

struct _a11 *next;

};



#endif


functions.h:

Código: [Seleccione]

#include <stdlib.h>

#include <string.h>

#include "structures.h"



is_single_exp *insert_function_exp(is_function *exp);

is_single_exp *insert_number_exp(int number);

is_single_exp *insert_var_exp(int line, char *var);

is_function *insert_op_function(is_function_op *op);

is_function *insert_deflocal_function(is_function_deflocal *deflocal);

is_function *insert_defun_function(is_function_defun *defun);

is_function *insert_if_simp_function(is_function_if_simp *if_simp);

is_function *insert_if_comp_function(is_function_if_comp *if_comp);

is_function *insert_user_function(is_function_user *user);

is_function *insert_not_function(is_function_not *not);

is_function_not *insert_not_function_exp(is_function *function);

is_function_not *insert_not_number_exp(int number);

is_function_not *insert_not_var_exp(int line, char *var);

is_arg_list *insert_arg_list(int line, char *arg, is_arg_list *next);

is_function_defun *insert_function_defun(int line, char *var, is_arg_list *args, is_single_exp_list *exp);

is_deflocal *insert_deflocal(char *var, is_single_exp *exp, int line);

is_function_deflocal *insert_function_deflocal(is_deflocal *def, is_function_deflocal *next);

is_function_if_comp *insert_function_if_comp(is_single_exp *test, is_single_exp *return_true, is_single_exp *return_false);

is_function_if_simp *insert_function_if_simp(is_single_exp *test, is_single_exp *return_true);

is_single_exp_list *insert_single_exp_list(is_single_exp *exp, is_single_exp_list *next);

is_function_user *insert_function_user(int line, char *var, is_single_exp_list *exp);

is_function_op *insert_function_op(is_op op, is_single_exp_list *exp, is_single_exp *exp_);

is_statement *insert_statement(is_single_exp *exp, is_statement *next);


functions.c:

Código: [Seleccione]

#include "functions.h"



is_single_exp *insert_function_exp(is_function *function)

{

is_single_exp *ise = (is_single_exp*) malloc(sizeof(is_single_exp));



ise->disc_se = d_function;

ise->data_exp.function = function;



return ise;

}



is_single_exp *insert_number_exp(int number)

{

is_single_exp *ise = (is_single_exp*) malloc(sizeof(is_single_exp));



ise->disc_se = d_NUMBER;

ise->data_exp.number = number;



return ise;

}



is_single_exp *insert_var_exp(int line, char *var)

{

is_single_exp *ise = (is_single_exp*) malloc(sizeof(is_single_exp));



ise->disc_se = d_VAR;

ise->data_exp.var = (char*) strdup(var);

ise->codeline = line;



return ise;

}



/* function structure */



is_function *insert_op_function(is_function_op *op)

{

is_function *is_f = (is_function*) malloc(sizeof(is_function));



is_f->disc_f = d_function_op;

is_f->data_exp.op = op;



return is_f;

}



is_function *insert_deflocal_function(is_function_deflocal *deflocal)

{

is_function *is_f = (is_function*) malloc(sizeof(is_function));



is_f->disc_f = d_function_deflocal;

is_f->data_exp.deflocal = deflocal;



return is_f;

}



is_function *insert_defun_function(is_function_defun *defun)

{

is_function *is_f = (is_function*) malloc(sizeof(is_function));



is_f->disc_f = d_function_defun;

is_f->data_exp.defun = defun;



return is_f;

}



is_function *insert_if_simp_function(is_function_if_simp *if_simp)

{

is_function *is_f = (is_function*) malloc(sizeof(is_function));



is_f->disc_f = d_function_if_simp;

is_f->data_exp.if_simp = if_simp;



return is_f;

}



is_function *insert_if_comp_function(is_function_if_comp *if_comp)

{

is_function *is_f = (is_function*) malloc(sizeof(is_function));



is_f->disc_f = d_function_if_comp;

is_f->data_exp.if_comp = if_comp;



return is_f;

}



is_function *insert_user_function(is_function_user *user)

{

is_function *is_f = (is_function*) malloc(sizeof(is_function));



is_f->disc_f = d_function_user;

is_f->data_exp.user = user;



return is_f;

}



is_function *insert_not_function(is_function_not *not)

{

is_function *is_f = (is_function*) malloc(sizeof(is_function));



is_f->disc_f = d_function_not;

is_f->data_exp.not = not;



return is_f;

}



/* Not */



is_function_not *insert_not_function_exp(is_function *function)

{

is_function_not *ifn = (is_function_not*) malloc(sizeof(is_function_not));



ifn->disc_fn = d_function;

ifn->data_exp.function = function;



return ifn;

}



is_function_not *insert_not_number_exp(int number)

{

is_function_not *ifn = (is_function_not*) malloc(sizeof(is_function_not));



ifn->disc_fn = d_NUMBER;

ifn->data_exp.number = number;



return ifn;

}



is_function_not *insert_not_var_exp(int line, char *var)

{

is_function_not *ifn = (is_function_not*) malloc(sizeof(is_function_not));



ifn->disc_fn = d_VAR;

ifn->data_exp.var = (char*) strdup(var);

ifn->codeline = line;



return ifn;

}



/* WTV */



is_arg_list *insert_arg_list(int line, char *arg, is_arg_list *next)

{

is_arg_list *ial = (is_arg_list*) malloc(sizeof(is_arg_list));



ial->arg = (char*) strdup(arg);

ial->codeline = line;



if (next == NULL)

return ial;



is_arg_list *aux;



for (aux = next; aux->next != NULL; aux = aux->next);



aux->next = ial;



return next;

}



is_function_defun *insert_function_defun(int line, char *var, is_arg_list *args, is_single_exp_list *exp)

{

is_function_defun *ifd = (is_function_defun*) malloc(sizeof(is_function_defun));



ifd->var = (char*) strdup(var);

ifd->args = args;

ifd->exp = exp;

ifd->codeline = line;



return ifd;

}



is_deflocal *insert_deflocal(char *var, is_single_exp *exp, int line)

{

is_deflocal *id = (is_deflocal*) malloc(sizeof(is_deflocal));



id->var = (char*) strdup(var);

id->exp = exp;

id->codeline = line;



return id;

}



is_function_deflocal *insert_function_deflocal(is_deflocal *def, is_function_deflocal *next)

{

is_function_deflocal *ifd = (is_function_deflocal*) malloc(sizeof(is_function_deflocal));



ifd->def = def;



if (next == NULL)

return ifd;



is_function_deflocal *aux;



for (aux = next; aux->next != NULL; aux = aux->next);



aux->next = ifd;



return next;

}



is_function_if_comp *insert_function_if_comp(is_single_exp *test, is_single_exp *return_true, is_single_exp *return_false)

{

is_function_if_comp *ific = (is_function_if_comp*) malloc(sizeof(is_function_if_comp));



ific->test = test;

ific->return_true = return_true;

ific->return_false = return_false;



return ific;

}



is_function_if_simp *insert_function_if_simp(is_single_exp *test, is_single_exp *return_true)

{

is_function_if_simp *ifis = (is_function_if_simp*) malloc(sizeof(is_function_if_simp));



ifis->test = test;

ifis->return_true = return_true;



return ifis;

}



is_single_exp_list *insert_single_exp_list(is_single_exp *exp, is_single_exp_list *next)

{

is_single_exp_list *isel = (is_single_exp_list*) malloc(sizeof(is_single_exp_list));



isel->exp = exp;



if (next == NULL)

return isel;



is_single_exp_list *aux;



for (aux = next; aux->next != NULL; aux = aux->next);



aux->next = isel;



return next;

}



is_function_user *insert_function_user(int line, char *var, is_single_exp_list *exp)

{

is_function_user *ifu = (is_function_user*) malloc(sizeof(is_function_user));



ifu->var = (char*) strdup(var);

ifu->exp = exp;

ifu->codeline = line;



return ifu;

}



is_function_op *insert_function_op(is_op op, is_single_exp_list *exp, is_single_exp *exp_)

{

is_function_op *ifo = (is_function_op*) malloc(sizeof(is_function_op));



ifo->op = op;

ifo->exp = exp;

ifo->exp_ = exp_;



return ifo;

}



is_statement *insert_statement(is_single_exp *exp, is_statement *next)

{

is_statement *is = (is_statement*) malloc(sizeof(is_statement));



is->exp = exp;



if (next == NULL)

return is;



is_statement *aux;



for (aux = next; aux->next != NULL; aux = aux->next);



aux->next = is;



return next;

}
My Q4 estimate: Macs: 5.89M; iPods: 4.19M; iPhones: 30.0M; iPads: 18.05M; Revenue: 37.00B; EPS: 9.50
AAPL Q3 result: Macs: 4.02M; iPods: 6.80M; iPhones: 26.0M; iPads: 17.04M; Revenue: 35.02B; EPS: 9.32

Offline KTachyon

  • Global Moderator
  • Newbie
  • *****
  • Mensagens: 0
  • Karma: +0/-0
    • Ver Perfil
    • http://twitter.com/KTachyon
Cross-Compiler - Código de um compilador
« Responder #4 em: Junho 18, 2006, 06:03:49 am »
Semântica:

Realiza a análise semântica, verificando se as variáveis são declaradas (se necessário), o nº de argumentos das funções corresponde, se estão a ser atribuidos valores às variáveis que são do mesmo tipo que as variáveis,... Caso haja um erro a função correspondente devolve-o.


symbol_table.h:

Código: [Seleccione]

#ifndef _SYMBOL_TABLE_

#define _SYMBOL_TABLE_



typedef struct _t1 {

char *name;

int offset;

struct _t1 *next;

} table_element;



typedef struct _t3 {

char *name;

struct _t3 *next;

table_element *args;

table_element *locals;

} user_functions;



typedef struct _t4 {

user_functions *ufunctions;

table_element *global;

} prog_env;



#endif


semantic.h:

Código: [Seleccione]

#include "structures.h"

#include "symbol_table.h"

#include <stdlib.h>

#include <string.h>

#include <stdio.h>



prog_env* semantic_analysis(is_statement *is);

void semantic_analysis_function(prog_env *pe, is_function *function);

void semantic_analysis_op(prog_env *pe, is_function_op *op);

void semantic_analysis_deflocal(prog_env *pe, is_function_deflocal *deflocal);

void semantic_analysis_vardeflocal(prog_env *pe, is_deflocal *def);

void semantic_analysis_defun(prog_env *pe, is_function_defun *defun);

void semantic_analysis_arg_list(is_arg_list *args);

void semantic_analysis_arg(int offset, char *arg, int line);

void semantic_analysis_if_simp(prog_env *pe, is_function_if_simp *if_simp);

void semantic_analysis_if_comp(prog_env *pe, is_function_if_comp *if_comp);

void semantic_analysis_user(prog_env *pe, is_function_user *user);

void semantic_analysis_not(prog_env *pe, is_function_not *not);

int semantic_analysis_single_exp_list(prog_env *pe, is_single_exp_list *isel);

void semantic_analysis_single_exp(prog_env *pe, is_single_exp *ise);



table_element* create_symbol(int offset, char* name);

table_element* lookup(table_element* table, char *str);

user_functions* lookup_uf(user_functions* table, char *str);


semantic.c:

Código: [Seleccione]

#include "semantic.h"



// offsets global e de função (local)

int global_offset = 0;

int function_offset = 0;

int local_offset = 0;



// Flag para impedir defuns condicionais

int if_scope = 0;



// Função actual (ou NULL). Serve como flag para impedir defuns dentro de defuns

user_functions *flag_function = NULL;



prog_env* semantic_analysis(is_statement *is)

{

is_statement *aux;



prog_env *pe = (prog_env*) malloc(sizeof(prog_env));



// Precorre as funções uma a uma (statements)

for (aux = is; aux; aux = aux->next)

{

function_offset = 0;



semantic_analysis_single_exp(pe, aux->exp);

}



return pe;

}



void semantic_analysis_function(prog_env *pe, is_function *function)

{

is_function_op *op = function->data_exp.op;

is_function_defun *defun = function->data_exp.defun;

is_function_deflocal *deflocal = function->data_exp.deflocal;

is_function_if_simp *if_simp = function->data_exp.if_simp;

is_function_if_comp *if_comp = function->data_exp.if_comp;

is_function_user *user = function->data_exp.user;

is_function_not *not = function->data_exp.not;



switch (function->disc_f)

{

case d_function_op: semantic_analysis_op(pe, op); break;

case d_function_deflocal: semantic_analysis_deflocal(pe, deflocal); break;

case d_function_defun:

// Se já estamos a definir uma função... ou se a definição é condicional...

if (flag_function)

{

printf("Line: %d - Error: Defun inside a defun: %s.n", defun->codeline, defun->var);

successful_semantic = 0;

}

else if (if_scope)

{

printf("Line: %d - Error: Conditional defun: %s.n", defun->codeline, defun->var);

successful_semantic = 0;

}

else

semantic_analysis_defun(pe, defun);

break;

case d_function_if_simp: semantic_analysis_if_simp(pe, if_simp); break;

case d_function_if_comp: semantic_analysis_if_comp(pe, if_comp); break;

case d_function_user: semantic_analysis_user(pe, user); break;

case d_function_not: semantic_analysis_not(pe, not); break;

}

}



void semantic_analysis_op(prog_env *pe, is_function_op *op)

{

semantic_analysis_single_exp_list(pe, op->exp);

semantic_analysis_single_exp(pe, op->exp_);

}



void semantic_analysis_deflocal(prog_env *pe, is_function_deflocal *deflocal)

{

is_function_deflocal *aux;



for(aux = deflocal; aux; aux = aux->next)

semantic_analysis_vardeflocal(pe, aux->def);

}



void semantic_analysis_vardeflocal(prog_env *pe, is_deflocal *def)

{

table_element *te;



// Está dentro de um defun?

if (flag_function)

{

// Já há variáveis na tabela?

if (flag_function->locals)

{

// Já está definida?

if (!lookup(flag_function->locals, def->var))

{

for (te = flag_function->locals; te->next; te = te->next);

te->next = create_symbol(local_offset++, def->var);

}

}

else

flag_function->locals = create_symbol(local_offset++, def->var);

}

else

{

// Já há variáveis na tabela?

if (pe->global)

{

// Já está definida?

if (!lookup(pe->global, def->var))

{

for (te = pe->global; te->next; te = te->next);

te->next = create_symbol(global_offset++, def->var);

}

}

else

pe->global = create_symbol(global_offset++, def->var);

}



semantic_analysis_single_exp(pe, def->exp);

}



void semantic_analysis_defun(prog_env *pe, is_function_defun *defun)

{

user_functions *aux_uf;

table_element *aux;



flag_function = lookup_uf(pe->ufunctions, defun->var);



if (flag_function)

{

// Se a função existir, dá erro.

printf("Line: %d - Error: Function already defined: %s.n", defun->codeline, defun->var);

successful_semantic = 0;

flag_function = NULL;

return;

}

else

// Se não existir, aloca espaço na memória para o criar

flag_function = (user_functions*) malloc(sizeof(user_functions));



flag_function->name = (char*) strdup(defun->var);



// Adiciona a função à lista de funções (ufunctions) do ambiente do programa (prog_env)

if (pe->ufunctions == NULL)

pe->ufunctions = flag_function;

else

{

for (aux_uf = pe->ufunctions; aux_uf->next; aux_uf = aux_uf->next);

aux_uf->next = flag_function;

}



semantic_analysis_arg_list(defun->args);

semantic_analysis_single_exp_list(pe, (is_single_exp_list*) defun->exp);



flag_function = NULL;

local_offset = 0;

}



void semantic_analysis_arg_list(is_arg_list *args)

{

is_arg_list *aux;



for (aux = args; aux; aux = aux->next)

semantic_analysis_arg(function_offset++, aux->arg, aux->codeline);

}



// Os argumentos apenas existem em defuns, logo flag_function não pode ser NULL

// Como os argumentos são as primeiras variáveis de um defun a serem adicionadas é possível impedir

// repetições de nomes de argumentos na lista de argumentos apenas verificando se na lista de variáveis

// da função ela já existe ou não.

// De resto é possível alterar o valor de uma argumento, dentro da função.

void semantic_analysis_arg(int offset, char *arg, int line)

{

table_element *aux;



// Verifica se já existe uma variável com o mm nome, rejeita

if (lookup(flag_function->args, arg))

{

printf("Line: %d - Error: Argument "%s" already defined.n", line, arg);

successful_semantic = 0;

}

else

// Se a tabela não está vazia...

if (flag_function->args)

{

for (aux = flag_function->args; aux->next; aux = aux->next);

aux->next = create_symbol(offset, arg);

}

else

flag_function->args = create_symbol(offset, arg);

}



// É possível a condição de teste de um if ser um defun, mas não é possível a existência de defuns

// condicionais (dentro dos campos de resultados).

void semantic_analysis_if_simp(prog_env *pe, is_function_if_simp *if_simp)

{

semantic_analysis_single_exp(pe, if_simp->test);

if_scope++;

semantic_analysis_single_exp(pe, if_simp->return_true);

if_scope--;

}



void semantic_analysis_if_comp(prog_env *pe, is_function_if_comp *if_comp)

{

semantic_analysis_single_exp(pe, if_comp->test);

if_scope++;

semantic_analysis_single_exp(pe, if_comp->return_true);

semantic_analysis_single_exp(pe, if_comp->return_false);

if_scope--;

}



void semantic_analysis_user(prog_env *pe, is_function_user *user)

{

int given_args, function_args = 0;

user_functions *uf = lookup_uf(pe->ufunctions, user->var);

table_element *te;



// Verifica se existe a função na tabela user_functions

if (!uf)

{

printf("Line: %d - Error: Unknown function: %s.n", user->codeline, user->var);

successful_semantic = 0;

}

else

{

given_args = semantic_analysis_single_exp_list(pe, user->exp);



for (te = uf->args; te; te = te->next)

function_args++;



if (given_args != function_args)

{

printf("Line: %d - Error: Function "%s" has an incorrect number of arguments: %d given, %d needed.n", user->codeline, user->var, given_args, function_args);

successful_semantic = 0;

}

}

}



void semantic_analysis_not(prog_env *pe, is_function_not *not)

{

// Vai ver que tipo de expressão é (função, variável ou número)

// Os números são imediatamente aceites

// Se for uma função, analiza a função, mas dá-lhe um scope local

// Se for uma variável, verifica se está numa das tabelas (global ou local)

if (not->disc_fn == d_function)

{

semantic_analysis_function(pe, not->data_exp.function);

}

else if (not->disc_fn == d_VAR)

{

// Verifica se a variável está na tabela local, caso esteja num defun

// Caso negativo, verifica se está na tabela global

// Caso negativo, mostra a mensagem de erro

if (flag_function)

if (flag_function->locals || flag_function->args)

if (lookup(flag_function->locals, not->data_exp.var) || lookup(flag_function->args, not->data_exp.var))

return;



if (!lookup(pe->global, not->data_exp.var))

{

printf("Line: %d - Error: Unknown variable: %s.n", not->codeline, not->data_exp.var);

successful_semantic = 0;

}

}

}



int semantic_analysis_single_exp_list(prog_env *pe, is_single_exp_list *isel)

{

is_single_exp_list *aux;

int count = 0;



for (aux = isel; aux; aux = aux->next) {

semantic_analysis_single_exp(pe, aux->exp);

count++;

}



return count;

}



void semantic_analysis_single_exp(prog_env *pe, is_single_exp *ise)

{

// Vai ver que tipo de expressão é

// Os números são imediatamente aceites

// Se for uma função, analiza a função, mas dá-lhe um scope de 1 para evitar defuns dentro de outras funções

// Se for uma variável, verifica se está numa das tabelas (global ou local)

if (ise->disc_se == d_function)

{

semantic_analysis_function(pe, ise->data_exp.function);

}

else if (ise->disc_se == d_VAR)

{

// Verifica se a variável está na tabela local, caso esteja num defun

// Caso negativo, verifica se está na tabela global

// Caso negativo, mostra a mensagem de erro

if (flag_function)

if (flag_function->locals || flag_function->args)

if (lookup(flag_function->locals, ise->data_exp.var) || lookup(flag_function->args, ise->data_exp.var))

return;



if (!lookup(pe->global, ise->data_exp.var))

{

printf("Line: %d - Error: Unknown variable: %s.n", ise->codeline, ise->data_exp.var);

successful_semantic = 0;

}

}

}



table_element* create_symbol(int offset, char* name)

{

table_element *elem = (table_element*) malloc(sizeof(table_element));

elem->name = strdup(name);

elem->next = NULL;

elem->offset = offset;



return elem;

}



table_element* lookup(table_element* table, char *str)

{

table_element *aux;



for (aux = table; aux; aux = aux->next)

if (strcmp(aux->name, str) == 0)

return aux;



return 0;

}



user_functions* lookup_uf(user_functions* table, char *str)

{

user_functions *aux;



for (aux = table; aux; aux = aux->next)

if (strcmp(aux->name, str) == 0)

return aux;



return 0;

}
My Q4 estimate: Macs: 5.89M; iPods: 4.19M; iPhones: 30.0M; iPads: 18.05M; Revenue: 37.00B; EPS: 9.50
AAPL Q3 result: Macs: 4.02M; iPods: 6.80M; iPhones: 26.0M; iPads: 17.04M; Revenue: 35.02B; EPS: 9.32

Offline KTachyon

  • Global Moderator
  • Newbie
  • *****
  • Mensagens: 0
  • Karma: +0/-0
    • Ver Perfil
    • http://twitter.com/KTachyon
Cross-Compiler - Código de um compilador
« Responder #5 em: Junho 18, 2006, 06:06:41 am »
Tradução:

Realiza a tradução do código em C (neste caso, por ser um cross-compiler para C). A conversão é feita para um C muito simplificado (extremamente semelhante a código assembly). Pode-se observar que cada instução em C corresponde práticamente a uma instrução assembly.


translation.h:

Código: [Seleccione]

#include "symbol_table.h"

#include "structures.h"

#include "semantic.h"

#include <stdio.h>



void translate(is_statement *stat, prog_env *pe);

void translate_header(FILE *dest);

void translate_statement(FILE *dest, prog_env *pe, is_statement *is);

void translate_function(FILE *dest, prog_env *pe, is_function *function);

void translate_defun(FILE *dest, prog_env *pe, is_function_defun *defun);

void translate_op(FILE *dest, prog_env *pe, is_function_op *op, is_function_if_simp *if_simp, is_function_if_comp *if_comp);

void translate_deflocal(FILE *dest, prog_env *pe, is_function_deflocal *deflocal);

void translate_vardeflocal(FILE *dest, prog_env *pe, is_deflocal *def);

void translate_if_simp(FILE *dest, prog_env *pe, is_function_if_simp *if_simp);

void translate_if_comp(FILE *dest, prog_env *pe, is_function_if_comp *if_comp);

void translate_user(FILE *dest, prog_env *pe, is_function_user *user);

void translate_not(FILE *dest, prog_env *pe, is_function_not *not, is_function_if_simp *if_simp, is_function_if_comp *if_comp);

void translate_single_exp(FILE *dest, prog_env *pe, is_single_exp *ise, int backup);

void translate_footer(FILE *dest);

void translate_redirector(FILE *dest);



void translate_simple_if_simp(FILE *dest, prog_env *pe, is_function_if_simp *if_simp);

void translate_simple_if_comp(FILE *dest, prog_env *pe, is_function_if_comp *if_comp);


translation.c:

[code]

#include "translation.h"



// Função actual...

user_functions *current_function_def;

user_functions *current_function_defun;



int return_counter;

int branch_counter_global;

int if_expr;



void translate(is_statement *stat, prog_env *pe)

{

   current_function_def = NULL;

   current_function_defun = NULL;

   

   return_counter = 0;

   branch_counter_global = 0;

   if_expr = 0;

   

   FILE *dest;

   dest = fopen("result.c", "w");

   

   translate_header(dest);

   translate_statement(dest, pe, stat);

   translate_footer(dest);

   

   fclose(dest);

}



void translate_header(FILE *dest)

{

   fprintf(dest, "#include "frame.h"n");

   fprintf(dest, "#include <stdio.h>n");

   fprintf(dest, "#include <stdlib.h>nn");

   fprintf(dest, "int main()n{n");

   fprintf(dest, "tint _ra;n");

   fprintf(dest, "tframe *gp, *sp, *fp;n");

   

   // Registos

   fprintf(dest, "tint _r6, _r7;nn");

   

   // Frames

   fprintf(dest, "tgp = (frame*) malloc(sizeof(frame));n");

   fprintf(dest, "tfp = gp;n");

   fprintf(dest, "tsp = gp;nn");

   

   fprintf(dest, "tgp->current_backup = 0;nn");

}



void translate_statement(FILE *dest, prog_env *pe, is_statement *is)

{

   is_statement *aux;

   

   for (aux = is; aux; aux = aux->next) {

      translate_single_exp(dest, pe, aux->exp, 0);

      fprintf(dest, "tprintf("%%d\\n", _r7);n");

   }

}



void translate_function(FILE *dest, prog_env *pe, is_function *function)

{

   is_function_op *op = function->data_exp.op;

   is_function_defun *defun = function->data_exp.defun;

   is_function_deflocal *deflocal = function->data_exp.deflocal;

   is_function_if_simp *if_simp = function->data_exp.if_simp;

   is_function_if_comp *if_comp = function->data_exp.if_comp;

   is_function_user *user = function->data_exp.user;

   is_function_not *not = function->data_exp.not;

   

   switch (function->disc_f)

   {

      case d_function_op: translate_op(dest, pe, op, NULL, NULL); break;

      case d_function_deflocal: translate_deflocal(dest, pe, deflocal); break;

      case d_function_defun: translate_defun(dest, pe, defun); break;

      case d_function_if_simp: translate_if_simp(dest, pe, if_simp); break;

      case d_function_if_comp: translate_if_comp(dest, pe, if_comp); break;

      case d_function_user: translate_user(dest, pe, user); break;

      case d_function_not: translate_not(dest, pe, not, NULL, NULL); break;

   }

}



void translate_defun(FILE *dest, prog_env *pe, is_function_defun *defun)

{

   fprintf(dest, "tgoto %s_skip;nn", defun->var);

   fprintf(dest, "%s:n", defun->var);

   

   fprintf(dest, "tfp = sp;n");

   fprintf(dest, "tsp = (frame*) malloc(sizeof(frame));n");

   fprintf(dest, "tsp->parent = fp;n");

   fprintf(dest, "tsp->current_backup = 0;n");

   fprintf(dest, "tsp->return_addr = _ra;n");

   

   current_function_defun = lookup_uf(pe->ufunctions, defun->var);

   

   is_single_exp_list *aux;

   

   for (aux = defun->exp; aux; aux = aux->next)

      translate_single_exp(dest, pe, aux->exp, 0);

   

   current_function_defun = NULL;

   

   fprintf(dest, "t_ra = sp->return_addr;n");

   fprintf(dest, "tsp = sp->parent;n");

   fprintf(dest, "tif (sp->parent) fp = sp->parent;n");

   

   fprintf(dest, "tgoto REDIRECTOR;nn");

   fprintf(dest, "%s_skip:n", defun->var);

   

   fprintf(dest, "t_r7 = 0;n", defun->var);

}



// BRB

void translate_op(FILE *dest, prog_env *pe, is_function_op *op, is_function_if_simp *if_simp, is_function_if_comp *if_comp)

{

   is_single_exp_list *aux = op->exp;

   int branch_counter = branch_counter_global++;

   

   translate_single_exp(dest, pe, aux->exp, 0);

   

   switch (op->op)

   {

      case is_SOMA:

      case is_SUB:

      case is_MULT:

      case is_DIV:

      case is_MAIOR:

      case is_MENOR:

      case is_MAIOR_IGUAL:

      case is_MENOR_IGUAL:

      case is_IGUAL:

      case is_XOR:

         fprintf(dest, "t_r6 = _r7;n");

         break;

      case is_AND: fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter); break;

      case is_OR: fprintf(dest, "tif (_r7) goto IF%dT;n", branch_counter); break;

   }

   

   for (aux = aux->next; aux; aux = aux->next)

   {

      translate_single_exp(dest, pe, aux->exp, 1);

      

      switch (op->op)

      {

         case is_SOMA: fprintf(dest, "t_r6 = _r6 + _r7;n"); break;

         case is_SUB: fprintf(dest, "t_r6 = _r6 - _r7;n"); break;

         case is_MULT: fprintf(dest, "t_r6 = _r6 * _r7;n"); break;

         case is_DIV: fprintf(dest, "t_r6 = _r6 / _r7;n"); break;

         case is_MAIOR:

            fprintf(dest, "t_r6 = _r6 > _r7;n");

            fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

            break;

         case is_MENOR:

            fprintf(dest, "t_r6 = _r6 < _r7;n");

            fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

            break;

         case is_MAIOR_IGUAL:

            fprintf(dest, "t_r6 = _r6 >= _r7;n");

            fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

            break;

         case is_MENOR_IGUAL:

            fprintf(dest, "t_r6 = _r6 <= _r7;n");

            fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

            break;

         case is_IGUAL: fprintf(dest, "tif (_r6 != _r7) goto IF%dF;n", branch_counter); break;

         case is_AND: fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter); break;

         case is_OR: fprintf(dest, "tif (_r7) goto IF%dT;n", branch_counter); break;

         case is_XOR:

            fprintf(dest, "t_r7 = _r7 && _r6;n");

            fprintf(dest, "tif (_r7) goto IF%dF;n", branch_counter);

            fprintf(dest, "tif (_r7) _r6 = _r7;n", branch_counter);

            break;

      }

   }

   

   translate_single_exp(dest, pe, op->exp_, 1);

   

   switch (op->op)

   {

      case is_SOMA: fprintf(dest, "t_r7 = _r6 + _r7;n"); break;

      case is_SUB: fprintf(dest, "t_r7 = _r6 - _r7;n"); break;

      case is_MULT: fprintf(dest, "t_r7 = _r6 * _r7;n"); break;

      case is_DIV: fprintf(dest, "t_r7 = _r6 / _r7;n"); break;

      case is_MAIOR:

         fprintf(dest, "t_r7 = _r6 > _r7;n");

         fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

         

         if (if_simp || if_comp)

         {

            if (if_simp)

               translate_single_exp(dest, pe, if_simp->return_true, 0);

            if (if_comp)

               translate_single_exp(dest, pe, if_comp->return_true, 0);

         }

         else

            fprintf(dest, "t_r7 = 1;n");

         

         fprintf(dest, "tgoto IF%dT;n", branch_counter);

         fprintf(dest, "IF%dF:n", branch_counter);

         

         if (if_comp)

            translate_single_exp(dest, pe, if_comp->return_false, 0);

         else

            fprintf(dest, "t_r7 = 0;n");

         

         fprintf(dest, "IF%dT:n", branch_counter);

         break;

      case is_MENOR:

         fprintf(dest, "t_r7 = _r6 < _r7;n");

         fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

         

         if (if_simp || if_comp)

         {

            if (if_simp)

               translate_single_exp(dest, pe, if_simp->return_true, 0);

            if (if_comp)

               translate_single_exp(dest, pe, if_comp->return_true, 0);

         }

         else

            fprintf(dest, "t_r7 = 1;n");

         

         fprintf(dest, "tgoto IF%dT;n", branch_counter);

         fprintf(dest, "IF%dF:n", branch_counter);

         

         if (if_comp)

            translate_single_exp(dest, pe, if_comp->return_false, 0);

         else

            fprintf(dest, "t_r7 = 0;n");

            

         fprintf(dest, "IF%dT:n", branch_counter);

         break;

      case is_MAIOR_IGUAL:

         fprintf(dest, "t_r7 = _r6 >= _r7;n");

         fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

         

         if (if_simp || if_comp)

         {

            if (if_simp)

               translate_single_exp(dest, pe, if_simp->return_true, 0);

            if (if_comp)

               translate_single_exp(dest, pe, if_comp->return_true, 0);

         }

         else

            fprintf(dest, "t_r7 = 1;n");

         

         fprintf(dest, "tgoto IF%dT;n", branch_counter);

         fprintf(dest, "IF%dF:n", branch_counter);

         

         if (if_comp)

            translate_single_exp(dest, pe, if_comp->return_false, 0);

         else

            fprintf(dest, "t_r7 = 0;n");

         

         fprintf(dest, "IF%dT:n", branch_counter);

         break;

      case is_MENOR_IGUAL:

         fprintf(dest, "t_r7 = _r6 <= _r7;n");

         fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

         

         if (if_simp || if_comp)

         {

            if (if_simp)

               translate_single_exp(dest, pe, if_simp->return_true, 0);

            if (if_comp)

               translate_single_exp(dest, pe, if_comp->return_true, 0);

         }

         else

            fprintf(dest, "t_r7 = 1;n");

         

         fprintf(dest, "tgoto IF%dT;n", branch_counter);

         fprintf(dest, "IF%dF:n", branch_counter);

         

         if (if_comp)

            translate_single_exp(dest, pe, if_comp->return_false, 0);

         else

            fprintf(dest, "t_r7 = 0;n");

         

         fprintf(dest, "IF%dT:n", branch_counter);

         break;

      case is_IGUAL:

         fprintf(dest, "tif (_r6 != _r7) goto IF%dF;n", branch_counter);

         

         if (if_simp || if_comp)

         {

            if (if_simp)

               translate_single_exp(dest, pe, if_simp->return_true, 0);

            if (if_comp)

               translate_single_exp(dest, pe, if_comp->return_true, 0);

         }

         else

            fprintf(dest, "t_r7 = 1;n");

         

         fprintf(dest, "tgoto IF%dT;n", branch_counter);

         fprintf(dest, "IF%dF:n", branch_counter);

         

         if (if_comp)

            translate_single_exp(dest, pe, if_comp->return_false, 0);

         else

            fprintf(dest, "t_r7 = 0;n");

         

         fprintf(dest, "IF%dT:n", branch_counter);

         break;

      case is_AND:

         fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

         

         if (if_simp || if_comp)

         {

            if (if_simp)

               translate_single_exp(dest, pe, if_simp->return_true, 0);

            if (if_comp)

               translate_single_exp(dest, pe, if_comp->return_true, 0);

         }

         else

            fprintf(dest, "t_r7 = 1;n");

         

         fprintf(dest, "tgoto IF%dT;n", branch_counter);

         fprintf(dest, "IF%dF:n", branch_counter);

         

         if (if_comp)

            translate_single_exp(dest, pe, if_comp->return_false, 0);

         else

            fprintf(dest, "t_r7 = 0;n");

         

         fprintf(dest, "IF%dT:n", branch_counter);

         break;

      case is_OR:

         fprintf(dest, "tif (_r7) goto IF%dT;n", branch_counter);

         

         if (if_comp)

            translate_single_exp(dest, pe, if_comp->return_false, 0);

         else

            fprintf(dest, "t_r7 = 0;n");

         

         fprintf(dest, "tgoto IF%dF;n", branch_counter);

         fprintf(dest, "IF%dT:n", branch_counter);

         

         if (if_simp || if_comp)

         {

            if (if_simp)

               translate_single_exp(dest, pe, if_simp->return_true, 0);

            if (if_comp)

               translate_single_exp(dest, pe, if_comp->return_true, 0);

         }

         else

            fprintf(dest, "t_r7 = 1;n");

         

         fprintf(dest, "IF%dF:n", branch_counter);

         break;

      case is_XOR:

         fprintf(dest, "t_r7 = _r7 && _r6;n");

         fprintf(dest, "tif (_r7) goto IF%dF;n", branch_counter);

         fprintf(dest, "t_r7 = _r7 || _r6;n");

         fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

         

         if (if_simp || if_comp)

         {

            if (if_simp)

               translate_single_exp(dest, pe, if_simp->return_true, 0);

            if (if_comp)

               translate_single_exp(dest, pe, if_comp->return_true, 0);

         }

         else

            fprintf(dest, "t_r7 = 1;n");

         

         fprintf(dest, "tgoto IF%dT;n", branch_counter);

         fprintf(dest, "IF%dF:n", branch_counter);

         

         if (if_comp)

            translate_single_exp(dest, pe, if_comp->return_false, 0);

         else

            fprintf(dest, "t_r7 = 0;n");

         

         fprintf(dest, "IF%dT:n", branch_counter);

         break;

   }

}



void translate_deflocal(FILE *dest, prog_env *pe, is_function_deflocal *deflocal)

{

   is_function_deflocal *aux;

   

   for(aux = deflocal; aux; aux = aux->next)

      translate_vardeflocal(dest, pe, aux->def);

   

   fprintf(dest, "t_r7 = 0;n");

}



void translate_vardeflocal(FILE *dest, prog_env *pe, is_deflocal *def)

{

   table_element *te;

   

   if (current_function_defun)

   {

      te = lookup(current_function_defun->locals, def->var);

      

      if (te)

      {

         translate_single_exp(dest, pe, def->exp, 0);

         fprintf(dest, "tsp->locals[%d] = _r7;n", te->offset);

      }

      else

      {

         te = lookup(pe->global, def->var);

         translate_single_exp(dest, pe, def->exp, 0);

         fprintf(dest, "tgp->locals[%d] = _r7;n", te->offset);

      }

   }

   else if (current_function_def)

   {

      te = lookup(current_function_def->locals, def->var);

      

      if (te)

      {

         translate_single_exp(dest, pe, def->exp, 0);

         fprintf(dest, "tsp->locals[%d] = _r7;n", te->offset);

      }

      else

      {

         te = lookup(pe->global, def->var);

         translate_single_exp(dest, pe, def->exp, 0);

         fprintf(dest, "tgp->locals[%d] = _r7;n", te->offset);

      }

   }

   else

   {

      te = lookup(pe->global, def->var);

      translate_single_exp(dest, pe, def->exp, 0);

      fprintf(dest, "tgp->locals[%d] = _r7;n", te->offset);

   }

}



void translate_if_simp(FILE *dest, prog_env *pe, is_function_if_simp *if_simp)

{

   is_function *function = NULL;

   

   if (if_simp->test->disc_se == d_function)

   {

      function = if_simp->test->data_exp.function;

      

      if (function->disc_f == d_function_not)

         translate_not(dest, pe, function->data_exp.not, if_simp, NULL);

      else if (function->disc_f == d_function_op)

      {

         switch (function->data_exp.op->op)

         {

            case is_MAIOR:

            case is_MENOR:

            case is_MAIOR_IGUAL:

            case is_MENOR_IGUAL:

            case is_IGUAL:

            case is_AND:

            case is_OR:

            case is_XOR:

               translate_op(dest, pe, function->data_exp.op, if_simp, NULL); break;

            default:

               translate_simple_if_simp(dest, pe, if_simp);

         }

      }

      else

         translate_simple_if_simp(dest, pe, if_simp);

   }

   else

      translate_simple_if_simp(dest, pe, if_simp);

}



void translate_simple_if_simp(FILE *dest, prog_env *pe, is_function_if_simp *if_simp)

{

   int branch_counter = branch_counter_global++;

   

   translate_single_exp(dest, pe, if_simp->test, 0);

   fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

   translate_single_exp(dest, pe, if_simp->return_true, 0);

   fprintf(dest, "tgoto IF%dT;n", branch_counter);

   fprintf(dest, "IF%dF:n", branch_counter);

   fprintf(dest, "t_r7 = 0;n");

   fprintf(dest, "IF%dT:n", branch_counter);

}



void translate_if_comp(FILE *dest, prog_env *pe, is_function_if_comp *if_comp)

{

   is_function *function = NULL;

   

   if (if_comp->test->disc_se == d_function)

   {

      function = if_comp->test->data_exp.function;

      

      if (function->disc_f == d_function_not)

         translate_not(dest, pe, function->data_exp.not, NULL, if_comp);

      else if (function->disc_f == d_function_op)

      {

         switch (function->data_exp.op->op)

         {

            case is_MAIOR:

            case is_MENOR:

            case is_MAIOR_IGUAL:

            case is_MENOR_IGUAL:

            case is_IGUAL:

            case is_AND:

            case is_OR:

            case is_XOR:

               translate_op(dest, pe, function->data_exp.op, NULL, if_comp); break;

            default:

               translate_simple_if_comp(dest, pe, if_comp);

         }

      }

      else

         translate_simple_if_comp(dest, pe, if_comp);

   }

   else

      translate_simple_if_comp(dest, pe, if_comp);

}



void translate_simple_if_comp(FILE *dest, prog_env *pe, is_function_if_comp *if_comp)

{

   int branch_counter = branch_counter_global++;

   

   translate_single_exp(dest, pe, if_comp->test, 0);

   fprintf(dest, "tif (!_r7) goto IF%dF;n", branch_counter);

   translate_single_exp(dest, pe, if_comp->return_true, 0);

   fprintf(dest, "tgoto IF%dT;n", branch_counter);

   fprintf(dest, "IF%dF:n", branch_counter);

   translate_single_exp(dest, pe, if_comp->return_false, 0);

   fprintf(dest, "IF%dT:n", branch_counter);

}



void translate_user(FILE *dest, prog_env *pe, is_function_user *user)

{

   current_function_def = lookup_uf(pe->ufunctions, user->var);

   

   // Colocar argumentos no outgoing da frame actual.

   is_single_exp_list *aux;

   int offset = 0;

   

   for (aux = user->exp; aux; aux = aux->next) {

      translate_single_exp(dest, pe, aux->exp, 0);

      fprintf(dest, "tsp->outgoing[%d] = _r7;n", offset++);

   }

   

   // Ir para o código da função.

   fprintf(dest, "t_ra = %d;n", return_counter);

   fprintf(dest, "tgoto %s;nn", user->var);

   fprintf(dest, "RETURN%d:n", return_counter);

   return_counter++;

   

   current_function_def = NULL;

}



void translate_not(FILE *dest, prog_env *pe, is_function_not *not, is_function_if_simp *if_simp, is_function_if_comp *if_comp)

{

   table_element *te;

   int branch_counter = branch_counter_global++;

   

   switch (not->disc_fn)

   {

      case d_function:

         translate_function(dest, pe, not->data_exp.function);

         break;

      case d_VAR:

         if (current_function_defun)

         {

            te = lookup(current_function_defun->locals, not->data_exp.var);

            

            if (te)

            {

               fprintf(dest, "t_r7 = sp->locals[%d];n", te->offset);

            }

            else

            {

               te = lookup(current_function_defun->args, not->data_exp.var);

               

               if (te)

               {

                  fprintf(dest, "t_r7 = fp->outgoing[%d];n", te->offset);

               }

               else

               {

                  te = lookup(pe->global, not->data_exp.var);

                  fprintf(dest, "t_r7 = gp->locals[%d];n", te->offset);

               }

            }

         }

         else if (current_function_def)

         {

            te = lookup(current_function_def->locals, not->data_exp.var);

            

            if (te)

            {

               fprintf(dest, "t_r7 = sp->locals[%d];n", te->offset);

            }

            else

            {

               te = lookup(pe->global, not->data_exp.var);

               fprintf(dest, "t_r7 = sp->locals[%d];n", te->offset);

            }

         }

         else

         {

            te = lookup(pe->global, not->data_exp.var);

            fprintf(dest, "t_r7 = sp->locals[%d];n", te->offset);

         }

         break;

      case d_NUMBER: fprintf(dest, "t_r7 = %d;n", not->data_exp.number); break;

   }

   

   fprintf(dest, "tif (_r7) goto IF%dF;n", branch_counter);

   

   if (if_simp || if_comp)

   {

      if (if_simp)

         translate_single_exp(dest, pe, if_simp->return_true, 0);

      if (if_comp)

         translate_single_exp(dest, pe, if_comp->return_true, 0);

   }

   else

      fprintf(dest, "t_r7 = 1;n");

   

   fprintf(dest, "tgoto IF%dT;n", branch_counter);

   fprintf(dest, "IF%dF:n", branch_counter);

   

   if (if_comp)

      translate_single_exp(dest, pe, if_comp->return_false, 0);

   else

      fprintf(dest, "t_r7 = 0;n");

   

   fprintf(dest, "IF%dT:n", branch_counter);

}



void translate_single_exp(FILE *dest, prog_env *pe, is_single_exp *ise, int backup)

{

   table_element *te;

   

   switch (ise->disc_se)

   {

      case d_function:

         if (backup)

         {

            fprintf(dest, "tsp->register_backup[sp->current_backup] = _r6;n");

            fprintf(dest, "tsp->current_backup++;n");

         }

         

         translate_function(dest, pe, ise->data_exp.function);

         

         if (backup)

         {
My Q4 estimate: Macs: 5.89M; iPods: 4.19M; iPhones: 30.0M; iPads: 18.05M; Revenue: 37.00B; EPS: 9.50
AAPL Q3 result: Macs: 4.02M; iPods: 6.80M; iPhones: 26.0M; iPads: 17.04M; Revenue: 35.02B; EPS: 9.32

Offline KTachyon

  • Global Moderator
  • Newbie
  • *****
  • Mensagens: 0
  • Karma: +0/-0
    • Ver Perfil
    • http://twitter.com/KTachyon
Cross-Compiler - Código de um compilador
« Responder #6 em: Junho 18, 2006, 06:08:31 am »
Frame:

Sendo isto um cross-compiler, é necessário um ficheiro extra que representa a memória no assembly. Este ficheiro é necessário para compilar o result.c (ficheiro com o resultado da compilação).


frame.h:

Código: [Seleccione]

typedef struct _f1 {

struct _f1* parent;

int return_addr;

int current_backup;

int register_backup[128];

int locals[64];

int outgoing[32];

} frame;
My Q4 estimate: Macs: 5.89M; iPods: 4.19M; iPhones: 30.0M; iPads: 18.05M; Revenue: 37.00B; EPS: 9.50
AAPL Q3 result: Macs: 4.02M; iPods: 6.80M; iPhones: 26.0M; iPads: 17.04M; Revenue: 35.02B; EPS: 9.32

Offline MrDeath

  • Newbie
  • *
  • Mensagens: 0
  • Karma: +0/-0
    • Ver Perfil
Cross-Compiler - Código de um compilador
« Responder #7 em: Julho 03, 2006, 05:38:27 pm »
Citação de: KhAoTiK_TaChYoN
Para algumas (ou uma) pessoa que não acredita que neste forum à pessoas capazes de criar um compilador
[/quote]

Todo mundo é capaz para fazer tal ato, mas tem que estudar é claro.

Enquanto ao compilador, parabéns!

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49