ARBOL.YAC



/* 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);
}