Advertisement
Salvioner

calc.y

Feb 6th, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.63 KB | None | 0 0
  1. /** calculator calc.y
  2.  * origin source by Tom Niemann at epaperpress.com/lexandyacc
  3.  * revision Lorenzo Massimo Gramola (2014)
  4.  * revision Lorenzo Massimo Gramola (2015): added node identifier for graph building
  5.  * revision Lorenzo Massimo Gramola (2016): removed previusly added useless comments
  6. */
  7.  
  8. %{
  9.     #include <stdio.h>
  10.     #include <stdlib.h>
  11.     #include <stdarg.h>
  12.       #include <string.h>
  13.     #include "calc.h"
  14.  
  15.     /* prototypes */
  16.     nodeType *opr(int oper, int nops, ...);
  17.     nodeType *id(char * i);
  18.     nodeType *con(int value);
  19.     void freeNode(nodeType *p);
  20.     int ex(nodeType *p);
  21.     int yylex(void);
  22.     void yyerror(char *s);
  23.     nodeType* createPoint(char *s);
  24.     nodeType* link(char* a, char* b);
  25.     nodeType* pointer(char* a);
  26.     int sym[26];                    /* symbol table */
  27.     nodeList lista;
  28.     nodeList* fine = &lista;
  29.     int uid = 0;
  30.     %}
  31.  
  32. %union {
  33.     int iValue;
  34.     char* sIndex;
  35.     nodeType *nPtr;
  36. };                              /* this cause a new type def to be generated,
  37.                                  which is a union of the above and and is called
  38.                                  YYSTYPE. Then there is the declaration
  39.                                  extern YYSTYPE yylval which declares yylval as
  40.                                  an external variable
  41.                                  */
  42.  
  43. %token <iValue> INTEGER         /* NOTE THIS DELCARATION*/
  44. %token <sIndex> VARIABLE
  45. %token WHILE IF PRINT
  46. %nonassoc IFX
  47. %nonassoc ELSE
  48.  
  49. %left GE LE EQ NE '>' '<'
  50. %left '+' '-'
  51. %left '*' '/'
  52. %nonassoc UMINUS
  53.  
  54. %type <nPtr> stmt expr stmt_list
  55.  
  56. %%
  57.  
  58. program:
  59.         function                   {ex(NULL); exit(0);}
  60.         ;
  61.  
  62. function:
  63.         function stmt              {ex($2);freeNode($2);}
  64.         | /* NULL */
  65.         ;
  66.  
  67. stmt:
  68.         ';'                                  {$$ = opr(';', 2, NULL, NULL);} //opr is of type "nodetype", we are putting in the stack a node
  69.         | expr ';'                           {$$ = $1;}
  70.         | PRINT expr ';'                     {$$ = opr(PRINT,1,$2);}
  71.         | VARIABLE '=' expr ';'              {createVar($1);
  72.                                                 $$ = opr('=',2,id($1),$3);
  73.  
  74.                                              } // remember id is another funtcion that returns a nodetype, we are passing a nodetype as id
  75.         | '<' VARIABLE '>' ';'               {$$ = createPoint($2);}        //inserire il puntatore7
  76.         | '<' VARIABLE '>' '=' expr ';'      {$$ = opr('=', 2, pointer($2), $5);}
  77.         | VARIABLE '=' '@' VARIABLE ';'      {$$ = link($1, $4);}
  78.         | WHILE '(' expr ')' stmt            {$$ = opr(WHILE,2,$3,$5);}
  79.         | IF '(' expr ')' stmt %prec IFX     {$$ = opr(IF,2,$3,$5);}
  80.         | IF '(' expr ')' stmt ELSE stmt     {$$ = opr(IF,3,$3,$5,$7);}
  81.         | '{' stmt_list '}'                  {$$ = $2;}
  82.         ;
  83.  
  84. stmt_list:
  85.         stmt                    { $$ = $1; }
  86.         | stmt_list stmt        { $$ = opr(';', 2, $1, $2); }
  87.         ;
  88. expr:
  89.         INTEGER                 {$$ = con($1);} //manage constants
  90.         | VARIABLE              {$$ = id($1);} //manage variables - namely an IDENTIFIER
  91.         | '<' VARIABLE '>'      {$$ = pointer($2);}
  92.         | '-' expr %prec UMINUS {$$ = opr(UMINUS,1,$2);}
  93.         | expr '+' expr         {$$ = opr('+',2,$1,$3);}
  94.         | expr '-' expr         {$$ = opr('-',2,$1,$3);}
  95.         | expr '*' expr         {$$ = opr('*',2,$1,$3);}
  96.         | expr '/' expr         {$$ = opr('/',2,$1,$3);}
  97.         | expr '<' expr         {$$ = opr('<',2,$1,$3);}
  98.         | expr '>' expr         {$$ = opr('>',2,$1,$3);}
  99.         | expr GE expr          {$$ = opr(GE,2,$1,$3);}
  100.         | expr LE expr          {$$ = opr(LE,2,$1,$3);}
  101.         | expr NE expr          {$$ = opr(NE,2,$1,$3);}
  102.         | expr EQ expr          {$$ = opr(EQ,2,$1,$3);}
  103.         | '(' expr ')'          {$$ = $2;}
  104.         ;
  105.  
  106. %%
  107.  
  108. void createVar(char* l){
  109.  
  110. nodeList * nodo = & lista;
  111.     while(nodo->prossimo != NULL){
  112.         nodo = nodo->prossimo;
  113.         if(strcmp(nodo->nome, l) == 0){
  114.             return ;
  115.        }
  116.     }
  117.  
  118.     nodeList* p;
  119.  
  120.     if((p=malloc(sizeof(nodeList))) == NULL){
  121.          yyerror("out of memory");
  122.     }
  123.  
  124.     p->puntatore = 0;
  125.     p->nome = l;
  126.  
  127.  
  128.  
  129.     fine->prossimo = p;
  130.     fine = p;
  131. }
  132.  
  133. nodeType* createPoint(char* l){
  134.     nodeList* p;
  135.  
  136.     if((p=malloc(sizeof(nodeList))) == NULL){
  137.          yyerror("out of memory");
  138.     }
  139.  
  140.     p->puntatore = 1;
  141.     p->nome = l;
  142.     p->nodo_puntato = NULL;
  143.     fine->prossimo = p;
  144.     fine = p;
  145.     return p;
  146. }
  147.  
  148. nodeType *con(int value){
  149.     nodeType *p;
  150.     /* allocate node space in memory */
  151.     if((p=malloc(sizeof(nodeType))) == NULL){
  152.         yyerror("out of memory");
  153.     }
  154.     /* copy information */
  155.     p->uid = uid++;
  156.     p->type = typeCon;
  157.     p->con.value = value;
  158.  
  159.     return p;
  160. }
  161.  
  162. /*
  163.  * Restituisce il valore dell'identificatore chiamato "i"
  164. */
  165. nodeType *id (char* i){
  166.     nodeType *p;
  167.     if((p=malloc(sizeof(nodeType)))==NULL){
  168.         yyerror("out of memory");
  169.     }
  170.     p->uid = uid++;
  171.     p->type = typeId;
  172.     nodeList * nodo = & lista;
  173.     printf(" ");
  174.     while(nodo->prossimo != NULL){
  175.        nodo = nodo->prossimo;
  176.         if(strcmp(nodo->nome, i) == 0){
  177.             p->id = nodo;
  178.             return p;
  179.        }
  180.     }
  181.  
  182.     yyerror("usato variabile non inizializzata");
  183.  
  184. }
  185.  
  186. nodeType* link(char* a, char* b){
  187.     nodeType* puntatore = id(a);
  188.     nodeType* puntato = id(b);
  189.     if(puntatore->id->puntatore == 1){
  190.         puntatore->id->nodo_puntato = puntato->id;
  191.         return puntatore;
  192.     }
  193.     else{
  194.         yyerror("variabile utilizzata non è un puntatore \n");
  195.     }
  196.  
  197.  
  198. }
  199.  
  200. nodeType* pointer(char* a){
  201.     nodeType* p = id(a);
  202.     nodeType* f;
  203.     if((f=malloc(sizeof(nodeType)))==NULL){
  204.         yyerror("out of memory");
  205.     }
  206.     if(p->id->puntatore == 1){
  207.         f->uid = uid++;
  208.         f->type = typeId;
  209.         f->id = p->id->nodo_puntato;
  210.         return f;
  211.     }
  212.     else{
  213.          yyerror("variabile utilizzata non è un puntatore \n");
  214.     }
  215.  
  216. }
  217.  
  218. nodeType *opr(int oper, int nops, ...){
  219.     va_list ap; /* (ap = argument pointer) va_list is used to declare a variable
  220.                  which, from time to time, is referring to an argument*/
  221.     nodeType *p;
  222.     int i;
  223.  
  224.     if ((p = malloc(sizeof(nodeType))) == NULL){
  225.         yyerror("out of memory");
  226.     }
  227.     if((p->opr.op = malloc(nops*sizeof(nodeType)))== NULL){
  228.         yyerror("out of memory");
  229.     }
  230.     p->uid = uid++;
  231.     p->type = typeOpr;
  232.     p->opr.oper = oper;
  233.     p->opr.nops = nops;
  234.     va_start(ap, nops);/* initialize the sequence, makes ap point to the first
  235.                         anonymous argument. Must call it once before reading all
  236.                         the parameters*/
  237.     for(i = 0; i<nops;i++){
  238.         p->opr.op[i]=va_arg(ap,nodeType*); /*every time va_arg is called it returns
  239.                                             an argument and moves the pointer forward
  240.                                             to the next argument. It uses a type name
  241.                                             to decide what kind of type to return and
  242.                                             how much to move forward the pointer.
  243.                                             */
  244.         p->opr.op[i]->uid = uid++;
  245.     }
  246.     va_end(ap); /* MUST be called BEFORE THE FUNCTION TERMINATES. it provides
  247.                  the necessary cleaning functions.*/
  248.  
  249.  
  250.     return p;
  251. }
  252.  
  253. void freeNode(nodeType *p){
  254.     int i;
  255.     if(!p) return;
  256.     if(p->type == typeOpr){
  257.         for(i=0;i<p->opr.nops; i++){
  258.             freeNode(p->opr.op[i]);
  259.         }
  260.         free(p->opr.op);
  261.     }
  262.     free(p);
  263. }
  264.  
  265. void yyerror(char *s){
  266.     fprintf(stdout,"%s\n",s);
  267. }
  268. int main(){
  269.     yyparse();
  270.     return 0;
  271. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement