Search this site
Embedded Files
Skip to main content
Skip to navigation
Página principal
Guia2Compiladores
Proyectos Compiladores
Mini SQL
Proyacto Logo
Leng. Manipulacion Polinomios
Mini-JavaScript
Formas
LitleQuilt
Mini-PostScript
GeneradorEnsamblador
Interprete Maquina Post
Compiladores
Guia3Compiladores
tercetos
GeneracionCodigo
Prog para calc conj Primero
Programacion Orientada a Objetos
Polimorfismo
Temario Estudio
Proyectos
Álbum de fotos digital
MiniPaint
FlappyBird
EditorBitmaps
Generador Evaluador Examenes
JuezEnLinea
MiniNapster
Página principal
Guia2Compiladores
Proyectos Compiladores
Mini SQL
Proyacto Logo
Leng. Manipulacion Polinomios
Mini-JavaScript
Formas
LitleQuilt
Mini-PostScript
GeneradorEnsamblador
Interprete Maquina Post
Compiladores
Guia3Compiladores
tercetos
GeneracionCodigo
Prog para calc conj Primero
Programacion Orientada a Objetos
Polimorfismo
Temario Estudio
Proyectos
Álbum de fotos digital
MiniPaint
FlappyBird
EditorBitmaps
Generador Evaluador Examenes
JuezEnLinea
MiniNapster
More
Página principal
Guia2Compiladores
Proyectos Compiladores
Mini SQL
Proyacto Logo
Leng. Manipulacion Polinomios
Mini-JavaScript
Formas
LitleQuilt
Mini-PostScript
GeneradorEnsamblador
Interprete Maquina Post
Compiladores
Guia3Compiladores
tercetos
GeneracionCodigo
Prog para calc conj Primero
Programacion Orientada a Objetos
Polimorfismo
Temario Estudio
Proyectos
Álbum de fotos digital
MiniPaint
FlappyBird
EditorBitmaps
Generador Evaluador Examenes
JuezEnLinea
MiniNapster
tercetos
TERCETOS
Con este programa pueden ver como se genera el codigo intermedio (en
este caso codigo de tres direcciones)
Codigo probado en ubuntu debe funcionar con modificaciones menores
en otros sist. operativos.
compilar con yacc -d hoc.y
La gramatica usada es similar a la de hoc
----------------------------------------------------------------------
%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct ifctrl {
char etiqCierto[100], etiqFalso[100];
} Ifctrl;
typedef struct casectrl {
char ultiEtiq[100];
char variaExpr[100];
} Casectrl;
typedef struct exprInfo {
Ifctrl ifetiqs;
char expre[100];
} ExprInfo;
extern int lineno;
void yyerror (char *s);
int yylex ();
void warning(char *s, char *t);
void execerror(char *s, char *t);
void fpecatch(int e);
%}
%union {
int numero;
char varia[100];
char etiq[100];
char etiqSig[100];
ExprInfo expre;
Ifctrl ifEtiqs;
Casectrl infoCase;
}
%token <numero> NUMBER
%token <varia> VAR
%token <etiq> IF WHILE FOR LPAREN DO
%token <etiqSig> CASE
%token ASIG ELSE SWITCH DEFAULT CALL
%type <expre> expr
%type <ifEtiqs> cond cond1
%type <infoCase> inicio_case
%right
'='
%left
OR
%left
AND
%left
GT GE LT LE EQ NE
%left
'+' '_'
%left
'*' '/'
%left
UNARYMINUS NOT
%right
%%
list: /* nada */
| list
| list stmt
{ }
| list expr
{ }
| list error
{ yyerrok; }
;
asgn: VAR ASIG expr { printf("\t%s = %s\n", $1, $3.expre); }
;
stmt: expr { ; }
| CALL VAR LPAREN arglist ')' {
printf("\tcall %s \n", $2); //exit(0);
}
| FOR LPAREN expr {
etiqnueva($1);
printf("%s:\n", $1);
} ';' cond1 ';' {
etiqnueva($2);
printf("%s:\n", $2);
}
expr {
printf("\tgoto %s\n", $1);
} ')' {
printf("%s:\n", $6.etiqCierto);
} stmt {
printf("\tgoto %s\n", $2);
printf("%s:\n", $6.etiqFalso);
}
| WHILE {
etiqnueva($1);
printf("%s:\n", $1);
} cond {
printf("%s:\n", $3.etiqCierto);
} stmt {
printf("\tgoto %s\n", $1);
printf("%s:\n", $3.etiqFalso);
}
| IF cond {
printf("%s:\n", $2.etiqCierto);
} stmt {
etiqnueva($1);
printf("\tgoto %s\n", $1);
printf("%s:\n", $2.etiqFalso);
} elseOpc {
printf("%s:\n", $1);
}
| DO {
etiqnueva($1);
printf("%s:\n", $1);
}
stmt WHILE cond {
printf("%s:\n", $5.etiqFalso);
printf("\tgoto %s\n", $1);
printf("%s:\n", $5.etiqCierto);
}
| '{' stmtlist '}' { ; }
| stmtcase
;
cond:
LPAREN expr ')' {
strcpy($$.etiqCierto, $2.ifetiqs.etiqCierto);
strcpy($$.etiqFalso, $2.ifetiqs.etiqFalso);;
}
;
cond1: expr {
strcpy($$.etiqCierto, $1.ifetiqs.etiqCierto);
strcpy($$.etiqFalso, $1.ifetiqs.etiqFalso);;
}
;
elseOpc : ELSE stmt
|
;
stmtlist: /* nada */
{ ; }
| stmtlist
| stmtlist stmt
;
stmtcase : inicio_case
DEFAULT stmt ';'
'}'{
printf("%s:\n", $1.ultiEtiq);
}
| inicio_case
'}' {
printf("%s:\n", $1.ultiEtiq);
}
;
inicio_case : SWITCH LPAREN expr ')' '{' {
strcpy($$.variaExpr, $3.expre);
etiqnueva($$.ultiEtiq);
}
| inicio_case
CASE expr ':' {
etiqnueva($2);
printf("\tif %s != %s goto %s\n", $1.variaExpr, $3.expre, $2);
}
stmt ';' {
printf("\tgoto %s\n",$1.ultiEtiq);
printf("%s:\n",$2);
strcpy($$.variaExpr,$1.variaExpr);
strcpy($$.ultiEtiq,$1.ultiEtiq);
}
;
expr: NUMBER {
tempnuevo($$.expre);
printf("\t%s = %d;\n", $$.expre, $1);
}
| VAR
{ strcpy($$.expre, $1); }
| asgn
| expr '+' expr {
tempnuevo($$.expre);
printf("\t%s = %s + %s;\n", $$.expre, $1.expre, $3.expre);
}
| expr '-' expr {
tempnuevo($$.expre);
printf("\t%s = %s - %s;\n", $$.expre, $1.expre, $3.expre); }
| expr '*' expr {
tempnuevo($$.expre);
printf("\t%s = %s * %s;\n", $$.expre, $1.expre, $3.expre); }
| expr '/' expr {
tempnuevo($$.expre);
printf("\t%s = %s / %s;\n", $$.expre, $1.expre, $3.expre); }
| expr '^' expr {
tempnuevo($$.expre);
printf("\t%s = %s ^ %s;\n", $$.expre, $1.expre, $3.expre);
}
|'-' expr %prec UNARYMINUS {
tempnuevo($$.expre);
printf("\t%s = - %s;\n", $$.expre, $2.expre);
}
| expr GT expr {
etiqnueva($$.ifetiqs.etiqCierto);
etiqnueva($$.ifetiqs.etiqFalso);
printf("\tif %s > %s goto %s\n",
$1.expre, $3.expre, $$.ifetiqs.etiqCierto);
printf("\tgoto %s\n", $$.ifetiqs.etiqFalso);
}
| expr GE expr {
etiqnueva($$.ifetiqs.etiqCierto);
etiqnueva($$.ifetiqs.etiqFalso);
printf("\tif %s >= %s goto %s\n",
$1.expre, $3.expre, $$.ifetiqs.etiqCierto);
printf("\tgoto %s\n", $$.ifetiqs.etiqFalso);
}
| expr LT expr {
etiqnueva($$.ifetiqs.etiqCierto);
etiqnueva($$.ifetiqs.etiqFalso);
printf("\tif %s < %s goto %s\n",
$1.expre ,$3.expre ,$$.ifetiqs.etiqCierto);
printf("\tgoto %s\n",$$.ifetiqs.etiqFalso);
}
| expr LE expr {
etiqnueva($$.ifetiqs.etiqCierto);
etiqnueva($$.ifetiqs.etiqFalso);
printf("\tif %s <= %s goto %s\n",
$1.expre, $3.expre, $$.ifetiqs.etiqCierto);
printf("\tgoto %s\n",$$.ifetiqs.etiqFalso);
}
| expr EQ expr {
etiqnueva($$.ifetiqs.etiqCierto);
etiqnueva($$.ifetiqs.etiqFalso);
printf("\tif %s = %s goto %s\n",
$1.expre, $3.expre, $$.ifetiqs.etiqCierto);
printf("\tgoto %s\n", $$.ifetiqs.etiqFalso);
}
| expr NE expr {
etiqnueva($$.ifetiqs.etiqCierto);
etiqnueva($$.ifetiqs.etiqFalso);
printf("\tif %s != %s goto %s\n",
$1.expre, $3.expre, $$.ifetiqs.etiqCierto);
printf("\tgoto %s\n",$$.ifetiqs.etiqFalso);
}
| expr AND {
printf("%s:\n", $1.ifetiqs.etiqCierto);
} expr {
printf("%s:\n", $1.ifetiqs.etiqFalso);
printf("\tgoto %s\n", $4.ifetiqs.etiqFalso);
strcpy($$.ifetiqs.etiqCierto, $4.ifetiqs.etiqCierto);
strcpy($$.ifetiqs.etiqFalso, $4.ifetiqs.etiqFalso);
}
| expr OR {
printf("%s:\n", $1.ifetiqs.etiqFalso);
} expr {
printf("%s:\n", $1.ifetiqs.etiqCierto);
printf("\tgoto %s\n", $4.ifetiqs.etiqCierto);
strcpy($$.ifetiqs.etiqCierto, $4.ifetiqs.etiqCierto);
strcpy($$.ifetiqs.etiqFalso, $4.ifetiqs.etiqFalso);
}
| NOT expr {
strcpy($$.ifetiqs.etiqCierto, $2.ifetiqs.etiqFalso);
strcpy($$.ifetiqs.etiqFalso, $2.ifetiqs.etiqCierto);
}
| LPAREN expr ')' {
strcpy($$.ifetiqs.etiqCierto, $2.ifetiqs.etiqCierto);
strcpy($$.ifetiqs.etiqFalso, $2.ifetiqs.etiqFalso);
}
;
arglist: /* nada */ { ; }
| VAR { printf("\tparam1 %s ", $1); }
| arglist ',' VAR { printf("\tparam %s ", $3);; }
;
%%
#include <ctype.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf begin;
char *progname;
void reverse(char s[]){
int i, j;
char c;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
void itochar(int x, char *buffer, int radix){
int i = 0 , n,s;
n = x;
while (n > 0){
s = n%radix;
n = n/radix;
buffer[i++] = '0' + s;
}
buffer[i] = '\0';
reverse(buffer);
}
void tempnuevo(char * s){
static actual=0;
strcpy(s, "tmp");
itochar(++actual, &(s[3]), 10);
}
void etiqnueva(char * s){
static actual=0;
strcpy(s, "etq");
itochar(++actual, &(s[3]), 10);
}
int main(int argc, char **argv){
/*int fpecatch();*/
progname = argv[0];
setjmp(begin);
signal(SIGFPE, fpecatch);
yyparse();
return 0;
}
void yyerror(char *s) {
warning(s, (char *)0);
}
void execerror(char *s, char *t){
warning(s, t);
longjmp(begin, 0);
}
void fpecatch(int e){
execerror("floating point exception", (char *) 0);
}
void warning(char *s, char *t){
fprintf (stderr, "%s: %s", progname, s);
if(t)
fprintf (stderr, " %s", t);
fprintf (stderr, "cerca de la linea %d\n", lineno);
}
-------------------------------------------------------------
compilar con
flex hoc.l
%option noyywrap
%{
typedef struct ifctrl {
char etiqCierto[100], etiqFalso[100];
} Ifctrl;
typedef struct casectrl {
char ultiEtiq[100];
char variaExpr[100];
} Casectrl;
typedef struct exprInfo {
Ifctrl ifetiqs;
char expre[100];
} ExprInfo;
#include "y.tab.h"
int lineno = 1;
%}
%START COMENT
%%
^[ \t]*"*" {BEGIN COMENT;}
<COMENT>.+ {;}
<COMENT>\n {BEGIN 0; lineno++;}
\( { return LPAREN;}
":=" { return ASIG;}
\< { return LT; }
\> { return GT; }
">=" { return GE; }
"<=" { return LE; }
"==" { return EQ; }
"!=" { return NE; }
SWITCH { return SWITCH;}
CASE { return CASE;}
DEFAULT { return DEFAULT;}
DO { return DO; }
IF { return IF; }
ELSE { return ELSE; }
WHILE { return WHILE; }
FOR { return FOR;}
CALL { return CALL; }
AND { return AND; }
OR { return OR; }
NOT { return NOT; }
[0-9]+ {
yylval.numero=atoi(yytext);
return NUMBER;
}
[A-Za-z_][A-Za-z0-9_]* {
strcpy(yylval.varia, yytext);
return VAR;
}
[ \t]+ { ; }
\n { lineno++; }
. { return yytext[0];}
-----------------------------------------------------------------------
compilar con
gcc y.tab.c lex.yy.c
ejecutar con
./a.out < ejem.txt
-----------------------------------------------------------------------
Gram=y.tab.c y.tab.h
all: $(Gram) lex.yy.c
@gcc -o hoc y.tab.c lex.yy.c
@echo Compiled
$(Gram): hoc.y
@yacc -d hoc.y
lex.yy.c: hoc.l
@flex hoc.l
clean:
@rm -f lex.yy.c *.tab.* hoc
@echo Clean
----------------------------------------------------------
compilar con
make
ejecutar con
./hoc < ejem.txt
----------------------------------------------------------
Ejemplos
----------------------------------------------------------
y := x
z := 4 + 8
----------------------------------------------------------
IF ( 8 > 6 ) x := 333
ELSE x := 456
----------------------------------------------------------
WHILE ( 8 > 6 ) x := 2233
----------------------------------------------------------
IF ( 1 > 2 AND 3 < 4 ) x:=22
ELSE x:= 44
y := 55
----------------------------------------------------------
IF ( 1 < 2 AND 3 < 4 AND 5 < 6 AND 7 < 8 AND 9 < 0)
x:=22
ELSE x:= 44
y := 55
----------------------------------------------------------
FOR ( i:=0 ; 1 < 2 ; i := i +1 )
x:=22
y := 55
----------------------------------------------------------
DO {
x:=22
} WHILE ( 1 < 2)
y := 55
----------------------------------------------------------
SWITCH ( A ) {
CASE 1: x := 20 ;
CASE 2: x := 30 ;
CASE 3: x := 40 ;
CASE 4: x := 50 ;
DEFAULT
x := 1000;
}
----------------------------------------------------------
Google Sites
Report abuse
Page details
Page updated
Google Sites
Report abuse