DERIVA.YAC



/* DERIVACION DE EXPRESIONES DE UNA VARIABLE {X} */
/* ==================================================*/
/* === Programa:    derivadas.yac                 ===*/
/* === TEcnica:     Dirigida por la sintAxis      ===*/
/* === Programador: J. Rafael R. ochoa            ===*/
/* ==================================================*/

%{
   struct genera
   {
      char de[80];
      char le[80];
   };
%}

%union
{ 
   struct genera *estructura;
   char str[80];
}

%token LEFT RIGHT MAS MENOS POR LINEA SALIR CUALQUIER_COSA
%token <str> NUM VAR
%type <estructura> expr factor termino

%%
/* producciones de la gramatica */
inicio  : cadena
        | cadena inicio
        | error LINEA {printf("\n:-) ");} inicio
        ;
cadena  : SALIR          { return 1; }
        | expr LINEA     {
                          if (!$1) return;
                          printf("\n%s\n\n",$1);
                          printf(" o~ok\n");
                          printf("/|\\\n");
                          printf(" M   ");
                         }
        | otro LINEA     { printf("error...capturado");}
        ;
otro    : CUALQUIER_COSA
        ;
expr    : expr MAS termino   { if (!$1 || !$3) $$ = NULL;
                               else
                               {
                                 $$ = reserva_mem();
                                 sprintf($$->le,"%s + %s",$1->le,$3->le);
                                 sprintf($$->de,"%s + %s",$1->de,$3->de);
                               }
                              }
        | expr MENOS termino   { if (!$1 || !$3) $$ = NULL;
                               else
                               {
                                 $$ = reserva_mem();
                                 sprintf($$->le,"%s - %s",$1->le,$3->le);
                                 sprintf($$->de,"%s - %s",$1->de,$3->de);
                               }
                              }

         | termino           {
                                if (!$1) $$ = NULL;
                                else
                                {
                                   $$ = reserva_mem();
                                   sprintf($$->le,"%s",$1->le);
                                   sprintf($$->de,"%s",$1->de);
                                }
                             }
         ;
termino  : termino POR factor    { if(!$1 || !$3) $$ = NULL;
                                else
                                {
                                   $$ = reserva_mem();
        sprintf($$->de,"%s * %s + %s * %s",$1->le,$3->de,$3->le,$1->de);
              sprintf($$->le,"%s * %s",$1->le,$3->le);
                                }
                              }
        | factor             {
                                if (!$1) $$ = NULL;
                                else
                                {
                                   $$ = reserva_mem();
                                   sprintf($$->le,"%s",$1->le);
                                   sprintf($$->de,"%s",$1->de);
                                }
                              }
        ;
factor : VAR                 { $$ = reserva_mem();
                                strcpy($$->le,"x");
                                strcpy($$->de,"1");
                              }
        | NUM                 { $$ = reserva_mem();
                                sprintf($$->le,"%s",$1);
                                strcpy($$->de,"0");
                              }
        | LEFT expr RIGHT     { $$ = reserva_mem();
                               sprintf($$->de,"(%s)",$2->de);
                               sprintf($$->le,"(%s)",$2->le);
                              }
        ;
%%

/* funciones auxiliares */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern int yylex();  /* Liga con la funcion yylex generada por LEX */
extern int yynerrs;

int yyparse();


void main(void)
{
   printf("\n\n");
   printf("=========================================\n");
   printf("Por ejemplo 3*x+x\n");
   printf("para terminar, teclee \"salir\"\n");
   printf("===================================INICIO\n\n");
   printf(":-) ");
   yyparse();
   printf ("\n\n:-) ok\n");
}

yyerror()           /* llamado por yyparse() cuando ocurra */
{                             /*   un error                          */
  printf("\n error de sintaxis \n");
  return 1;
}

struct genera *reserva_mem(void)
{
   return (struct genera *)malloc(sizeof(struct genera));
}