Advertisement
alexarcan

lexical_analiser_final

Mar 30th, 2016
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.35 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include <malloc.h>
  6. #define SIZE 2046
  7.  
  8. #define SAFEALLOC(var,Type) if((var=(Type*)malloc(sizeof(Type)))==NULL)err("not enough memory");
  9.  
  10. enum{
  11.     ID, END,
  12.     //constants
  13.     CT_INT, CT_REAL, CT_CHAR, CT_STRING,
  14.     //keywords
  15.     BREAK, CHAR, DOUBLE, ELSE, FOR, IF, INT, RETURN, STRUCT, VOID, WHILE,
  16.     //delimiters
  17.     COMMA, SEMICOLON, LPAR, RPAR, LBRACKET, RBRACKET, LACC, RACC,
  18.     //operators
  19.     ADD, SUB, MUL, DIV, DOT, AND, OR, NOT, ASSIGN, EQUAL, NOTEQ, LESS, LESSEQ, GREATER, GREATEREQ,
  20.     SPACE, LINECOMMENT, COMMENT
  21. }; //tokens codes
  22.  
  23. typedef struct _Token
  24. {
  25.     int code;
  26.     union{
  27.         char *text;
  28.         long int i;
  29.         double r;
  30.         };
  31.     int line;
  32.     struct _Token *next;
  33. }Token;
  34.  
  35. Token *tokens;
  36. Token *lastToken = NULL;
  37. const char *pCrtCh;
  38. int line;
  39.  
  40. void err(const char *fmt,...)
  41. {
  42.     va_list va;
  43.     va_start(va,fmt);
  44.     fprintf(stderr,"error: ");
  45.     vfprintf(stderr,fmt,va);
  46.     fputc('\n',stderr);
  47.     va_end(va);
  48.     exit(-1);
  49. }
  50.  
  51.  
  52. void tkerr(const Token *tk,const char *fmt,...)
  53. {
  54.     va_list va;
  55.     va_start(va,fmt);
  56.     fprintf(stderr,"error in line %d: ",tk->line);
  57.     vfprintf(stderr,fmt,va);
  58.     fputc('\n',stderr);
  59.     va_end(va);
  60.     exit(-1);
  61. }
  62.  
  63.  
  64. Token *addTk(int code)
  65. {
  66.     Token *tk;
  67.     SAFEALLOC(tk,Token)
  68.     tk->code=code;
  69.     tk->line=line;
  70.     tk->next=NULL;
  71.     if(lastToken)
  72.     {
  73.         lastToken->next=tk;
  74.     }
  75.     else
  76.     {
  77.         tokens=tk;
  78.     }
  79.     lastToken=tk;
  80.     return tk;
  81. }
  82.  
  83. char* createString(const char *pStartCh,const char *pCrtCh)
  84. {
  85.     int nCh=pCrtCh-pStartCh+1;
  86.     char *str;
  87.     str=(char *)malloc(nCh*sizeof(char));
  88.     snprintf(str,nCh,"%s",pStartCh);
  89.     return str;
  90. }
  91.  
  92. char escCode(char ch)
  93. {
  94.     char newCh;
  95.     switch(ch)
  96.     {
  97.         case 'a': newCh='\a'; break;
  98.         case 'b': newCh='\b'; break;
  99.         case 'f': newCh='\f'; break;
  100.         case 'n': newCh='\n'; break;
  101.         case 'r': newCh='\r'; break;
  102.         case 't': newCh='\t'; break;
  103.         case '\'': newCh='\''; break;
  104.         case '\?': newCh='\?'; break;
  105.         case '\"': newCh='\"'; break;
  106.         case '\\': newCh='\\'; break;
  107.         case '0': newCh='\0'; break;
  108.     }
  109.     return newCh;
  110. }
  111.  
  112.  
  113. int getNextToken()
  114. {
  115.     int state=0,nCh;
  116.     char ch;
  117.     const char *pStartCh;
  118.     Token *tk;
  119.  
  120.     long int ct_int;
  121.     double ct_real;
  122.     int ct_char;
  123.     char *ct_string;
  124.     char *p;
  125.     int noBacks=0;
  126.     int i; 
  127.    
  128.     while(1)
  129.     {
  130.         ch=*pCrtCh;
  131.         printf("state: %d, character:%c\n",state,ch);
  132.         switch(state)
  133.         {
  134.             case 0:
  135.             if(ch==' '||ch=='\r'||ch=='\t')
  136.             {
  137.                 pCrtCh++; // consume the characterand remains in state 0
  138.             }
  139.             else if(ch=='\n')//handled separately in order to update the current line
  140.             {
  141.                 line++;
  142.                 pCrtCh++;
  143.             }
  144.             else if(ch>='1' || ch<='9')
  145.             {
  146.                 pCrtCh++;
  147.                 state=1;     
  148.             }
  149.             else if(ch=='0')
  150.             {
  151.                 pCrtCh++;
  152.                 state=2;
  153.             }
  154.             if(ch=='/')
  155.             {
  156.                 pCrtCh++;
  157.                 state=24;          
  158.             }
  159.             else if(ch=='\'')
  160.             {
  161.                 pStartCh=pCrtCh; // ?
  162.                 pCrtCh++;
  163.                 state=14;          
  164.             }
  165.             else if(ch=='\"')
  166.             {
  167.                 pStartCh=pCrtCh; // ?
  168.                 pCrtCh++;
  169.                 state=18;
  170.             }
  171.            
  172.             else if(ch==',')
  173.             {
  174.                     pCrtCh++;
  175.                     addTk(COMMA);
  176.                     return COMMA;
  177.             }
  178.             else if(ch==';')
  179.             {
  180.                     pCrtCh++;
  181.                     addTk(SEMICOLON);
  182.                     return SEMICOLON;
  183.             }
  184.             else if(ch=='(')
  185.             {
  186.                     pCrtCh++;
  187.                     addTk(LPAR);
  188.                     return LPAR;
  189.             }
  190.             else if(ch==')')
  191.             {
  192.                     pCrtCh++;
  193.                     addTk(RPAR);
  194.                     return RPAR;
  195.             }
  196.             else if(ch=='[')
  197.             {
  198.                     pCrtCh++;
  199.                     addTk(LBRACKET);
  200.                     return LBRACKET;
  201.             }
  202.             else if(ch==']')
  203.             {
  204.                     pCrtCh++;
  205.                     addTk(RBRACKET);
  206.                     return RBRACKET;
  207.             }
  208.             else if(ch=='{')
  209.             {
  210.                     pCrtCh++;
  211.                     addTk(LACC);
  212.                     return LACC;
  213.             }
  214.             else if(ch=='}')
  215.             {
  216.                     pCrtCh++;
  217.                     addTk(RACC);
  218.                     return RACC;
  219.             }
  220.             else if(ch=='+')
  221.             {
  222.                     pCrtCh++;
  223.                     addTk(ADD);
  224.                     return ADD;
  225.             }
  226.             else if(ch=='-')
  227.             {
  228.                     pCrtCh++;
  229.                     addTk(SUB);
  230.                     return SUB;
  231.             }
  232.             else if(ch=='*')
  233.             {
  234.                     pCrtCh++;
  235.                     addTk(MUL);
  236.                     return MUL;
  237.             }
  238.             else if(ch=='.')
  239.             {
  240.                     pCrtCh++;
  241.                     addTk(DOT);
  242.                     return DOT;
  243.             }
  244.             else if(ch=='&')
  245.             {
  246.                     pCrtCh++;
  247.                     state=43;
  248.             }
  249.             else if(ch=='|')
  250.             {
  251.                     pCrtCh++;
  252.                     state=45;
  253.             }
  254.             else if(ch=='!')
  255.             {
  256.                     pCrtCh++;
  257.                     state=47;
  258.             }
  259.             else if(ch=='=')
  260.             {
  261.                     pCrtCh++;
  262.                     state=48;
  263.             }
  264.             else if(ch=='<')
  265.             {
  266.                     pCrtCh++;
  267.                     state=51;
  268.             }
  269.             else if(ch=='>')
  270.             {
  271.                     pCrtCh++;
  272.                     state=54;
  273.             }
  274.            
  275.             else if(ch==0) //the end of the input string
  276.             {
  277.                 addTk(END);
  278.                 return END;
  279.             }          
  280.             else tkerr(addTk(END),"invalid character");
  281.            
  282.            
  283.             break;
  284.            
  285.             case 1:
  286.                 if(ch>='0'&&ch<='9')
  287.                 {
  288.                     pCrtCh++;
  289.                     //state=1;
  290.                 }
  291.                 else if(ch=='.')
  292.                 {
  293.                     pCrtCh++;
  294.                     state=8;
  295.                 }
  296.                 else if(ch=='e'||ch=='E')
  297.                 {
  298.                     pCrtCh++;
  299.                     state=10;
  300.                 }
  301.                 else
  302.                     state=6;
  303.                 break;
  304.             case 2:
  305.                 if(ch=='x'||ch=='X')
  306.                 {
  307.                     pCrtCh++;
  308.                     state=4;
  309.                 }
  310.                 else
  311.                     state=3;
  312.                 break;
  313.             case 3:
  314.                 if(ch>='0'&&ch<='7')
  315.                 {
  316.                     pCrtCh++;
  317.                     //state=3;
  318.                 }
  319.                 else if(ch=='.')
  320.                 {
  321.                     pCrtCh++;
  322.                     state=8;
  323.                 }
  324.                 else if(ch=='e'||ch=='E')
  325.                 {
  326.                     pCrtCh++;
  327.                     state=10;
  328.                 }
  329.                 else
  330.                     state=6;
  331.                 break;
  332.             case 4:
  333.                 if((ch>='0'&&ch<='9') || (ch>='a'&&ch<='f') || (ch>='A'&&ch<='F'))
  334.                 {
  335.                     pCrtCh++;
  336.                     state=5;
  337.                 }
  338.                 else
  339.                     tkerr(addTk(END),"not a valid int");
  340.                 break;
  341.             case 5:
  342.                 if((ch>='0'&&ch<='9') || (ch>='a'&&ch<='f') || (ch>='A'&&ch<='F'))
  343.                 {
  344.                     pCrtCh++;
  345.                 }
  346.                 else
  347.                     state=6;
  348.                 break;
  349.             case 6: //CT_INT
  350.                 ct_int=strtol(pStartCh,NULL,0);
  351.                 tk=addTk(CT_INT);
  352.                 tk->i=ct_int;
  353.                 return CT_INT;
  354.             case 8:
  355.                 if(ch>='0'&&ch<='9')
  356.                 {
  357.                     pCrtCh++;
  358.                     state=9;
  359.                 }
  360.                 // error?
  361.                 else
  362.                     tkerr(addTk(END),"after a point should be a digit");
  363.                 break;
  364.             case 9:
  365.                 if(ch=='e'||ch=='E')
  366.                 {
  367.                     pCrtCh++;
  368.                     state=10;
  369.                 }
  370.                 else if(ch>='0'&&ch<='9')
  371.                 {
  372.                     pCrtCh++;
  373.                 }
  374.                 else state=13;
  375.                 break;
  376.             case 10:
  377.                 if(ch=='+'||ch=='-')
  378.                 {
  379.                     pCrtCh++;
  380.                     state=11;
  381.                 }
  382.                 else
  383.                     state=11;
  384.                 break;
  385.              case 11:
  386.                 if(ch>='0'&&ch<='9')
  387.                 {
  388.                     pCrtCh++;
  389.                     state=12;
  390.                 }
  391.                 else
  392.                     tkerr(addTk(END),"after + or - should come a digit");
  393.                 break; 
  394.              case 12:
  395.                 if(ch>='0'&&ch<='9')
  396.                 {
  397.                     pCrtCh++;
  398.                 }
  399.                 else
  400.                     state=13;
  401.                 break;
  402.             case 13:
  403.                 ct_real=strtod(pStartCh,NULL);
  404.                 tk=addTk(CT_REAL);
  405.                 tk->r=ct_real;
  406.                 return CT_REAL;
  407.             case 14:
  408.                 if(ch=='\\')
  409.                 {
  410.                     pCrtCh++;
  411.                     state=15;
  412.                 }
  413.             else if(ch!='\'')
  414.                 {
  415.                     ct_char=ch;
  416.                     pCrtCh++;
  417.                     state=16;
  418.                 }
  419.                 else                    
  420.                     tkerr(addTk(END),"not a quote");
  421.                
  422.             else
  423.                 tkerr(addTk(END),"should come a character to be escaped");
  424.                 break;
  425.            
  426.             case 15:
  427.                 if(strchr("abfnrtv'?\"\\0", ch))
  428.                 {
  429.                     ct_char=escCode(ch);
  430.                     pCrtCh++;
  431.                     state=17;
  432.                 }
  433.                 else
  434.                     tkerr(addTk(END),"should come a character to be escaped");
  435.            
  436.             case 16:
  437.                 if(ch=='\'')
  438.                 {
  439.                     pCrtCh++;
  440.                     state=17;
  441.                 }
  442.                 else
  443.                 tkerr(addTk(END),"not a quote");
  444.                 break;
  445.            
  446.             case 17:
  447.                 tk=addTk(CT_CHAR);
  448.                 tk->i=ct_char;
  449.                 return CT_CHAR;
  450.                
  451.             case 18:
  452.                 if(ch=='\\')
  453.                 {
  454.                     pCrtCh++;
  455.                     state=19;
  456.                 }
  457.                 else if(ch!='"\\')
  458.                 {
  459.                     pCrtCh++;
  460.                     state=20;
  461.                 }
  462.                  else if (ch=='\"')
  463.                 {
  464.                     pCrtCh++;
  465.                     state=21;
  466.                 }
  467.            
  468.             case 19:
  469.                  if(strchr("abfnrtv'?\"\\0", ch))
  470.                 {
  471.                     pCrtCh++;
  472.                     state=20;
  473.                 }
  474.                 else
  475.                     tkerr(addTk(END),"should come a character to be escaped");
  476.             case 20:
  477.                  if(ch=='\"')
  478.                 {
  479.                     pCrtCh++;
  480.                     state=21;
  481.                 }
  482.                 else
  483.                     state=18;
  484.                 break;
  485.             case 21:
  486.                 ct_string=createString(pStartCh+1,pCrtCh-1);
  487.  
  488.                 while((p=strchr(ct_string,'\\'))!=NULL)
  489.                 {
  490.                     //p=strchr(ct_string,'\\');
  491.                     //puts(p);
  492.                     memmove(p,p+1,strlen(p));
  493.                     *p=escCode(*p);
  494.                 }
  495.                 tk=addTk(CT_STRING);
  496.                 tk->text=ct_string;
  497.                 return CT_STRING;
  498.             case 24:
  499.                 if(ch=='*')
  500.                 {
  501.                     pCrtCh++;
  502.                     state=27;
  503.                 }
  504.                 else if(ch=='/')
  505.                 {
  506.                     pCrtCh++;
  507.                     state=25;
  508.                 }
  509.                 else
  510.                 {
  511.                     addTk(DIV);
  512.                     return DIV;
  513.                 }
  514.                 break;
  515.             case 25: //LINECOMMENT
  516.                 if(ch=='\r'||ch=='\0')
  517.                 {
  518.                     pCrtCh++;
  519.                     state=0;
  520.                 }
  521.                 else if(ch=='\n')
  522.                 {
  523.                     line++;
  524.                     pCrtCh++;
  525.                     state=0;
  526.                 }
  527.                 else
  528.                 {
  529.                     pCrtCh++;                    
  530.                 }
  531.            
  532.             case 27:
  533.                 if(ch=='*')
  534.                 {
  535.                     pCrtCh++;
  536.                     state=28;
  537.                 }
  538.                 else pCrtCh++;
  539.                 break;
  540.            
  541.             case 28:
  542.                 if(ch=='/')
  543.                 {
  544.                     pCrtCh++;
  545.                     state=0; //COMMENT
  546.                 }
  547.                 else if(ch=='*')
  548.                 {
  549.                     pCrtCh++;
  550.                     state=28;
  551.                 }
  552.                 else
  553.                 {
  554.                     pCrtCh++;
  555.                     state=27;
  556.                 }
  557.                 break;
  558.            
  559.             /*case 2:
  560.                 nCh=pCrtCh-pStartCh;//the id length
  561.                 //keywords tests
  562.                 if(nCh==5&&!memcmp(pStartCh,"break",5))tk=addTk(BREAK);
  563.                 else if(nCh==4&&!memcmp(pStartCh,"char",4))tk=addTk(CHAR);
  564.                 //...all keywords...
  565.                 else //if no keyword, then it is an ID
  566.                 {
  567.                 tk=addTk(ID);
  568.                 tk->text=createString(pStartCh,pCrtCh);
  569.                 }
  570.                 return tk->code;
  571.             */
  572.            
  573.             case 43:
  574.                 if(ch=='&')
  575.                 {
  576.                     pCrtCh++;
  577.                     addTk(AND);
  578.                 }
  579.                 else
  580.                     tkerr(addTk(END),"should come a &");
  581.                 break;
  582.             case 45:
  583.                 if(ch=='|')
  584.                 {
  585.                     pCrtCh++;
  586.                     addTk(OR);
  587.                 }
  588.                 else
  589.                     tkerr(addTk(END),"should come a |");
  590.                 break;
  591.             case 45:
  592.                 if(ch=='=')
  593.                 {
  594.                     pCrtCh++;
  595.                     addTk(NOTEQ);
  596.                     return NOTEQ;
  597.                 }
  598.                 else{
  599.                     addTk(NOT);
  600.                     return NOT;
  601.                 }
  602.                    
  603.            
  604.             case 48:
  605.                 if(ch=='=')
  606.                 {  
  607.                     pCrtCh++;
  608.                     addTk(EQUAL);
  609.                     return EQUAL;
  610.                 }
  611.                 else
  612.                 {
  613.                     addTk(ASSIGN);
  614.                     return ASSIGN;
  615.                 }
  616.            
  617.             case 51:
  618.                 if(ch=='=')
  619.                 {  
  620.                     pCrtCh++;
  621.                     addTk(LESSEQ);
  622.                     return LESSEQ;
  623.                 }
  624.                 else
  625.                 {
  626.                     addTk(LESS);
  627.                     return LESS;
  628.                 }
  629.             case 54:
  630.                 if(ch=='=')
  631.                 {  
  632.                     pCrtCh++;
  633.                     addTk(GREATEREQ);
  634.                     return GREATEREQ;
  635.                 }
  636.                 else
  637.                 {
  638.                     addTk(GREATER);
  639.                     return GREATER;
  640.                 }
  641.            
  642.            
  643.         }  
  644.        
  645.     }
  646. }
  647.  
  648. void printTokens()
  649. {
  650.     Token *current=tokens;
  651.     while(current!=NULL)
  652.     {
  653.         printf("%i", current->code);
  654.         switch(current->code)
  655.         {
  656.             case ID:
  657.             case CT_STRING:
  658.             printf(":%s",current->text);
  659.             break;
  660.             case CT_CHAR:
  661.             printf(":%c",(int)current->i);
  662.             break;
  663.             case CT_INT:
  664.             printf(":%li",current->i);
  665.             break;
  666.             case CT_REAL:
  667.             printf(":%lf",current->r);
  668.             break;
  669.         }
  670.         printf(" ");
  671.         current=current->next;
  672.     }
  673.     printf("\n");
  674. }
  675.  
  676. void getTokens()
  677. {
  678.     do
  679.     {
  680.         getNextToken();
  681.     }while(*pCrtCh);
  682. }
  683.  
  684. int main()
  685. {
  686.     FILE *file=fopen("8.c","r+");
  687.     if(file==NULL)
  688.     {
  689.         printf("The file could not be opened.\n");
  690.         exit(1);
  691.     }
  692.     char *input;
  693.     int size;
  694.  
  695.     fseek(file, 0, SEEK_END); // seek to end of file
  696.     size = ftell(file); // get current file pointer
  697.     fseek(file, 0, SEEK_SET); // seek back to beginning of file
  698.  
  699.     input=(char *)malloc((size+1)*sizeof(char));
  700.     fread(input,sizeof(char),size,file);
  701.     input[size]='\0';
  702.     pCrtCh=input;
  703.     getTokens();
  704.     printTokens();
  705.     fclose(file);
  706.     return 0;
  707. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement