SHARE
TWEET

Untitled

a guest Nov 19th, 2019 70 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2.  
  3. #include <ctype.h> //isspace
  4. #include <math.h> //pow
  5. #include <stdio.h>
  6. #include <stdlib.h> //NULL EOF
  7.  
  8. // Token types
  9. enum tokens {
  10.     ADD, SUB, MUL, DIV, MOD, POW,
  11.     OBR, CBR,
  12.     VAL, NON,
  13.     ERR, NEXT,
  14.     EXP
  15. //  More later
  16. };
  17.  
  18. //Token data structure
  19.  
  20. typedef struct token {
  21. //enum tokens type; if doesn't work
  22.     tokens type;
  23.     double value; //item to save the value
  24. } Token;
  25.  
  26. //Scanner states
  27. enum states{
  28.     INIT,
  29.     ZERO,
  30.     DOT,
  31.     FRACT,
  32.     EXPO,
  33.     PRESHIFT,
  34.     SHIFT
  35. };
  36.  
  37.  
  38.  
  39. // SCANNER (LEXICAL ANALYZER)
  40. Token scanner() {
  41.     Token token = { NON, 0 };
  42.     states state = INIT;
  43.     int c;
  44.     static int last = EOF;  //indicator that there was any remember symbol
  45.    
  46.     if(last != EOF && !isspace(last))
  47.         c = last;
  48.     else
  49.         while(isspace(c = getchar())); //We will skip all the white space characters
  50.    
  51.     last = EOF;
  52.    
  53.     switch(c){
  54.         case '+':
  55.             token.type = ADD;
  56.             return token;
  57.         case '-':
  58.             token.type = SUB;
  59.             return token;
  60.         case '*':
  61.             token.type = MUL;
  62.             return token;
  63.         case '/':
  64.             token.type = DIV;
  65.             return token;
  66.         case '%':
  67.             token.type = MOD;
  68.             return token;
  69.         case '^':
  70.             token.type = POW;
  71.             return token;
  72.         case '(':
  73.             token.type = OBR;
  74.             return token;
  75.         case ')':
  76.             token.type = CBR;
  77.             return token;
  78.         case EOF:
  79.             return token;
  80.         default:
  81.             if(isdigit(c))
  82.                 break;
  83.            
  84.             token.type = ERR;
  85.             return token;
  86.            
  87.     }
  88.    
  89.     token.type = VAL;
  90.     token.value += c - '0'; //variable that Host the character that host the number
  91.    
  92.     double fractional = 1;
  93.    
  94.     int exponential=0;
  95.    
  96.     int sign = 0;
  97.     for(;;){
  98.         c = getchar();
  99.         switch(state){
  100.                 case INIT:
  101.                     if(isdigit(c))
  102.                         token.value = token.value *10 + c - '0'; //order of our numerical decimal base
  103.                     else
  104.                     {
  105.                     if(c == '.')
  106.                         state = DOT;
  107.                         else if(c=='e' || c=='E') //EXPONENTIAL PART
  108.                             state=EXPO;
  109.                     else
  110.                     {
  111.                         last = c;
  112.                         return token;
  113.                     }
  114.                     }
  115.                 break;
  116.                
  117.                 case DOT:
  118.                     if(!isdigit(c))
  119.                     {
  120.                         token.type = ERR;
  121.                         return token;
  122.                     }
  123.  
  124.                     fractional /= 10;
  125.                     token.value += fractional * (c - '0');
  126.                     state = FRACT;
  127.                     break;
  128.                
  129.                 case FRACT:
  130.                     if(isdigit(c))
  131.                     {
  132.                         fractional /= 10;
  133.                         token.value += fractional * (c - '0');
  134.                     }else
  135.                         //Exponential TODO
  136.                         if(c == 'e' || 'E')
  137.                             state = EXPO;
  138.                     else
  139.                     {
  140.                         last = c;
  141.                         return token;
  142.                     }
  143.                 break;
  144.                 //case TODO after the Exponential part
  145.             case EXPO:
  146.                if(!isdigit(c))
  147.                {
  148.                    if(c=='-'){
  149.                        if(isdigit(c=getchar())){
  150.                            do{
  151.                                exponential = exponential*10 + c - '0';
  152.                                exponential*=1;
  153.                            }while(isdigit(c=getchar()));
  154.                            token.value=pow(token.value,exponential);
  155.                            return token;
  156.                        }
  157.                    }
  158.                    token.type=ERR;
  159.                    return token;
  160.                }
  161.                else{
  162.                    do{
  163.                        exponential = exponential*10 + c - '0';
  164.                    }while(isdigit(c=getchar()));
  165.                    token.value=pow(token.value,exponential);
  166.                    return token;
  167.                }
  168.                         break;
  169.         }//chiusura switch
  170.        
  171.     }
  172.         return token;
  173.    
  174.    
  175.    
  176.    
  177. }
  178.  
  179. //pushdown
  180. typedef struct pushdown Stack;
  181. struct pushdown{
  182.     Token token;
  183.     Stack *next;
  184. };
  185.  
  186. Stack *pop(Stack *stack){
  187.     if(stack != NULL)
  188.     {
  189.         Stack *tmp = stack->next;
  190.         free(stack);
  191.         stack = tmp;
  192.     }
  193.     return stack;
  194.    
  195. }
  196.  
  197. void freeStack(Stack *stack){
  198.     while(stack != NULL)
  199.         stack = pop(stack);
  200. }
  201.  
  202.  
  203. Stack *push(Stack *stack, Token token){
  204.     Stack *tmp;
  205.     if((tmp = (Stack *)malloc(sizeof(Stack))) == NULL)
  206.     {
  207.         freeStack(stack);
  208.         return NULL;
  209.     }
  210.     tmp->token = token;
  211.     tmp->next = stack;
  212.     return tmp;
  213. }
  214. /*void printStack(Stack *stack){
  215.     if(stack != NULL){
  216.         if(stack->token.type == VAL || stack->token.type == EXP)
  217.             printf("-[%d|%g]", stack->token.type, stack->token.value);
  218.         printStack(stack->next);
  219.     }
  220.     else
  221.         printf("\n");
  222. }
  223. */
  224. //Top most terminal
  225.  
  226. tokens topTerminal(Stack *stack){
  227.     for(; stack != NULL; stack = stack->next)
  228.         if(stack->token.type != EXP){
  229.             return stack->token.type;
  230. }
  231.     return ERR; //Fatal Error
  232. }
  233.  
  234.  
  235. //Table values
  236. enum table { L,G,E,B,A};
  237. //Precedence Table
  238. static table precTable[10][10] = {
  239. //        +  -  *  /  %  ^  (  )  N  $
  240. /* + */ { G, L, L, L, L, L, L, G, L, G },
  241. /* - */ { G, L, L, L, L, L, L, G, L, G },
  242. /* * */ { G, L, G, G, G, L, L, G, L, G },
  243. /* / */ { G, L, G, G, G, L, L, G, L, G },
  244. /* % */ { G, L, G, G, G, L, L, G, L, G },
  245. /* ^ */ { G, L, G, G, G, L, L, G, L, G },
  246. /* ( */ { L, L, L, L, L, L, L, E, L, B },
  247. /* ) */ { G, G, G, G, G, G, B, G, B, G },
  248. /* N */ { G, G, G, G, G, G, B, G, B, G },
  249. /* $ */ { L, L, L, L, L, L, L, B, L, A },
  250. };
  251.  
  252. int main(){
  253.     double value;
  254.     Token token = {NON , 0}; //end marker
  255.     Stack *stack = NULL;
  256.     if((stack = push(stack, token)) == NULL)
  257.         goto mallocError;
  258.     token.type = NEXT;
  259.    
  260.     // Parser Loop
  261.     for(;;){
  262.         if(token.type == NEXT)
  263.             token = scanner();
  264.         if(token.type == ERR)
  265.             goto lexicalError;
  266.        
  267.         switch(precTable[topTerminal(stack)][token.type]){
  268.             case L:
  269.                 if((stack = push(stack, token))==NULL)
  270.                     goto mallocError;
  271.                 token.type = NEXT;
  272.                 break;
  273.    
  274.             case E:
  275.                 Stack *tmp;
  276.                 if((tmp = push(stack, token))==NULL)
  277.                     goto mallocError;
  278.                 token.type = NEXT;
  279.                 stack = tmp;
  280.                 break;
  281.                
  282.             case G:
  283.                 switch(topTerminal(stack)){
  284.                        
  285.                     case ADD: //E->E + E
  286.                         if(stack->token.type != EXP)
  287.                             goto syntaxError;
  288.                         value = stack -> token.value;
  289.                         stack = pop(stack);
  290.                         if(stack->token.type != ADD)
  291.                             goto syntaxError;
  292.                             stack = pop(stack);
  293.                         if(stack->token.type != EXP)
  294.                             goto syntaxError;
  295.                         stack->token.value += value;
  296.                         continue;
  297.                        
  298.                     case SUB: //E->E - E | E-> -E
  299.                         if(stack->token.type != EXP)
  300.                             goto syntaxError;
  301.                         value = stack->token.value;
  302.                         stack = pop(stack);
  303.                         if(stack->token.type != SUB)
  304.                             goto syntaxError;
  305.                         if(stack->next->token.type == EXP)
  306.                         {
  307.                             stack = pop(stack);
  308.                             stack->token.value -= value;
  309.                            
  310.                         }
  311.                         else
  312.                             stack->token.value -= value;
  313.                         stack->token.type = EXP;
  314.                         continue;
  315.                        
  316.                     case MUL: //E->E * E
  317.                         if(stack->token.type != EXP)
  318.                             goto syntaxError;
  319.                         value = stack -> token.value;
  320.                         stack = pop(stack);
  321.                         if(stack->token.type != MUL)
  322.                             goto syntaxError;
  323.                             stack = pop(stack);
  324.                         if(stack->token.type != EXP)
  325.                             goto syntaxError;
  326.                         stack->token.value *= value;
  327.                         continue;
  328.                        
  329.                     case DIV:
  330.                         if(stack->token.type != EXP)
  331.                             goto syntaxError;
  332.                         value = stack->token.value;
  333.                         stack = pop(stack);
  334.                         if(stack->token.type != DIV)
  335.                             goto syntaxError;
  336.                         stack = pop(stack);
  337.                         if(stack->token.type != EXP)
  338.                             goto syntaxError;
  339.                         stack->token.value /= value;
  340.                         continue;
  341.                    
  342.                     case MOD:
  343.                         if(stack->token.type != EXP)
  344.                             goto syntaxError;
  345.                         value = stack->token.value;
  346.                         stack = pop(stack);
  347.                         if(stack->token.type != MOD)
  348.                             goto syntaxError;
  349.                         stack = pop(stack);
  350.                         if(stack->token.type != EXP)
  351.                             goto syntaxError;
  352.                         stack->token.value = fmod(stack->token.value, value);
  353.                         continue;
  354.                        
  355.                     case POW: // E^E
  356.                         if(stack->token.type != EXP)
  357.                             goto syntaxError;
  358.                         value = stack->token.value;
  359.                         stack = pop(stack);
  360.                         if(stack->token.type != POW)
  361.                             goto syntaxError;
  362.                         stack = pop(stack);
  363.                         if(stack->token.type != EXP)
  364.                             goto syntaxError;
  365.                         stack->token.value = pow(stack->token.value, value);
  366.                         continue;
  367.                      
  368.                     case CBR:
  369.                         if(stack->token.type != CBR)
  370.                             goto syntaxError;
  371.                         stack = pop(stack);
  372.                         if(stack->token.type != EXP)
  373.                             goto syntaxError;
  374.                         value = stack->token.value;
  375.                         stack = pop(stack);
  376.                         if(stack->token.type != OBR)
  377.                             goto syntaxError;
  378.                         stack->token.value = value;
  379.                         stack->token.type = EXP;
  380.                         continue;
  381.                        
  382.                    
  383.                     case VAL: //E -> n rules on the notebook near the operand table
  384.                         if(stack->token.type != VAL)
  385.                             goto syntaxError;
  386.                         stack->token.type = EXP;
  387.                         continue;
  388.                        
  389.                 }
  390.            
  391.             case B:
  392.                 goto syntaxError;
  393.                
  394.             case A:
  395.                 if(stack->token.type == EXP)
  396.                     printf("%g\n", stack->token.value);
  397.                     freeStack(stack);
  398.                     return 0;
  399.                
  400.             default:
  401.                 goto fatalError;
  402.         }
  403.     }
  404.    
  405.    
  406.    
  407. mallocError:
  408.     perror("malloc error");
  409.     return 4;
  410. lexicalError:
  411.     fprintf(stderr, "Lexical error\n");
  412.     freeStack(stack);
  413.     return 3;
  414. syntaxError:
  415.     fprintf(stderr, "Syntax error\n");
  416.     freeStack(stack);
  417.     return 2;
  418. fatalError:
  419.     fprintf(stderr, "Fatal error\n");
  420.     freeStack(stack);
  421.     return 1;
  422. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top