/* CALCULADORA */
/* ==================================================*/
/* === Programa: arbol.yac ===*/
/* === TEcnica: Dirigida por la sintAxis ===*/
/* === Programador: J. Rafael R. Ochoa ===*/
/* ==================================================*/
%{
struct genera
{
char dato[2];
struct genera *izq;
struct genera *cen;
struct genera *der;
};
%}
%union
{
struct genera *hoja;
char str[80];
}
%token LEFT RIGHT MAS MENOS POR ENTRE LINEA SALIR CUALQUIER_COSA
%token <str> NUM VAR
%type <hoja> expr fac_ter inicio
%%
/* producciones de la gramatica */
inicio : SALIR { return 1; }
| expr LINEA
{
$$ = reserva_mem("S");
$$->izq = $1->izq;
$$->cen = $1->cen;
$$->der = $1->der;
show_tree($$);
return 1;
}
;
expr : expr MAS fac_ter
{
$$ = reserva_mem("R");
$$->izq = reserva_mem("e");
$$->cen = reserva_mem("+");
$$->der = reserva_mem("f");
$$->izq->izq = $1->izq;
$$->izq->cen = $1->cen;
$$->izq->der = $1->der;
$$->der->izq = $3->izq;
$$->der->cen = $3->cen;
$$->der->der = $3->der;
}
| expr MENOS fac_ter
{
$$ = reserva_mem("R");
$$->izq = reserva_mem("e");
$$->cen = reserva_mem("-");
$$->der = reserva_mem("f");
$$->izq->izq = $1->izq;
$$->izq->cen = $1->cen;
$$->izq->der = $1->der;
$$->der->izq = $3->izq;
$$->der->cen = $3->cen;
$$->der->der = $3->der;
}
| expr POR fac_ter
{
$$ = reserva_mem("R");
$$->izq = reserva_mem("e");
$$->cen = reserva_mem("*");
$$->der = reserva_mem("f");
$$->izq->izq = $1->izq;
$$->izq->cen = $1->cen;
$$->izq->der = $1->der;
$$->der->izq = $3->izq;
$$->der->cen = $3->cen;
$$->der->der = $3->der;
}
| expr ENTRE fac_ter
{
$$ = reserva_mem("R");
$$->izq = reserva_mem("e");
$$->cen = reserva_mem("/");
$$->der = reserva_mem("f");
$$->izq->izq = $1->izq;
$$->izq->cen = $1->cen;
$$->izq->der = $1->der;
$$->der->izq = $3->izq;
$$->der->cen = $3->cen;
$$->der->der = $3->der;
}
| fac_ter
{
$$ = reserva_mem("R");
$$->cen = reserva_mem("f");
$$->cen->izq = $1->izq;
$$->cen->cen = $1->cen;
$$->cen->der = $1->der;
}
;
fac_ter : VAR
{
$$ = reserva_mem("R");
$$->cen = reserva_mem("x");
}
| NUM
{
$$ = reserva_mem("R");
$$->cen = reserva_mem($1);
}
| LEFT expr RIGHT
{
$$ = reserva_mem("R");
$$->izq = reserva_mem("(");
$$->cen = reserva_mem("e");
$$->der = reserva_mem(")");
$$->cen->izq = $2->izq;
$$->cen->cen = $2->cen;
$$->cen->der = $2->der;
}
;
%%
/* funciones auxiliares */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define delta 30
extern int yylex(); /* Liga con la funcion yylex generada por LEX */
extern int yynerrs;
FILE *out;
int yyparse();
struct genera *reserva_mem(char cad[2]);
void show_tree(struct genera *);
void archiva_arbol(int, int, int, int, struct genera *);
void main(void)
{
printf(":-) ");
yyparse();
printf ("\n\n:-) ok\n");
}
yyerror()
{ printf("\n error de sintaxis \n"); return 1; }
struct genera *reserva_mem(char cad[2])
{
struct genera *nodo_nuevo = NULL;
nodo_nuevo = (struct genera *)malloc(sizeof(struct genera));
sprintf(nodo_nuevo->dato,"%s",cad);
nodo_nuevo->izq = NULL;
nodo_nuevo->cen = NULL;
nodo_nuevo->der = NULL;
return nodo_nuevo;
}
void show_tree(struct genera *lista)
{
int x=200,y=10; // datos para centrar al arbol a lo ancho
if ((out = fopen("datos.arb", "wt")) == NULL)
{ printf("No se puede crear el archivo de salida\n"); return; }
archiva_arbol(x,y,x,y,lista);
fprintf(out, "ok\n");
fclose(out);
}
void archiva_arbol(int x1, int y1, int x2, int y2, struct genera *lista)
{
fprintf(out, "%d\n",x1);
fprintf(out, "%d\n",y1);
fprintf(out, "%d\n",x2);
fprintf(out, "%d\n",y2);
fprintf(out, "%s\n", lista->dato);
if(lista->izq) archiva_arbol(x2,y2,x2-60,y2+30,lista->izq);
if(lista->cen) archiva_arbol(x2,y2,x2,y2+30,lista->cen);
if(lista->der) archiva_arbol(x2,y2,x2+60,y2+30,lista->der);
}