lolamontes69

K+R Exercise5_18

Sep 25th, 2014
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.11 KB | None | 0 0
  1. /* Make dcl recover from input errors
  2. */
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7.  
  8. #define MAXTOKEN 100
  9. #define BUFSIZE 100  
  10.  
  11. enum {NAME, PARENS, BRACKETS}; /* NAME is 0, PARENS has val 1, BRACKETS 2 */
  12.  
  13. void dcl(void);
  14. void dirdcl(void);
  15. void clearbuffs(void);
  16.  
  17. int gettoken(void);
  18. int tokentype;           /* type of last token */
  19. int lastchar;
  20.  
  21. char token[MAXTOKEN];    /* last token string */
  22. char name[MAXTOKEN];     /* identifier name */
  23. char datatype[MAXTOKEN]; /* data type = char, int, etc. */
  24. char out[1000];
  25.  
  26. char buf[BUFSIZE];
  27. int bufp = 0;            /* next free position in buffer    */
  28.  
  29.  
  30. main()  /* convert declaration to words */
  31. {
  32.     int c;
  33.     while(gettoken() != EOF) {     /* 1st token on line */
  34.         strcpy(datatype, token);   /* is the datatype   */
  35.         out[0] = '\0';
  36.         if(!isalpha(datatype[0])) {
  37.             for( ; (c = getch()) !='\n'; )
  38.                 ;
  39.             puts("error: invalid datatype");
  40.             clearbuffs();
  41.         }
  42.         else if(tokentype==NAME || tokentype==PARENS || tokentype==BRACKETS || \
  43.            tokentype=='*') {
  44.             dcl();                     /* parse rest of line if valid */
  45.         }
  46.         else if(tokentype!='\n') {
  47.             for( ; (c = getch()) !='\n'; )
  48.             printf("syntax error\n");
  49.             clearbuffs();
  50.         }
  51.         if(tokentype=='\n') {
  52.             if(lastchar=='[' || lastchar=='(') printf("error: unclosed %c\n",lastchar);
  53.             else printf("%s: %s %s\n", name, out, datatype);
  54.             clearbuffs();
  55.         }
  56.     }
  57.     return 0;
  58. }
  59.  
  60. int gettoken(void)        /* return next token */
  61. {
  62.     int c, getch(void);   /* Note the function prototype getch*/
  63.     void ungetch(int);
  64.     char *p = token;
  65.  
  66.     while((c=getch())==' ' || c == '\t')
  67.         ;
  68.     if(c == '(') {
  69.         if((c = getch()) == ')') {
  70.             lastchar=0;
  71.             strcpy(token, "()");
  72.             return tokentype = PARENS;
  73.         } else {
  74.             lastchar = '(';
  75.             ungetch(c);
  76.             return tokentype = '(';
  77.         }
  78.     } else if(c == '[') {
  79.         for(*p++ =c; (*p++ = (c=getch())) != ']'; ) {
  80.             if(!isalnum(c)) {
  81.                 lastchar = '[';
  82.                 return tokentype=c;
  83.             }
  84.         } *p = '\0';
  85.         lastchar=']';
  86.         return tokentype = BRACKETS;
  87.     } else if(isalpha(c)) {
  88.         for(*p++ = c; isalnum(c = getch()); )
  89.             *p++ = c;
  90.         *p = '\0';
  91.         ungetch(c);
  92.         return tokentype = NAME;
  93.     } else {
  94.         if(c==')' || c==']')
  95.             lastchar=c;
  96.         return tokentype = c;
  97.     }
  98. }
  99.  
  100. /* get a (possibly pushed-back) character */
  101. int getch(void)
  102. {
  103.     return (bufp > 0) ? buf[--bufp] : getchar();
  104. }
  105.  
  106. /* push character back on input */
  107. void ungetch(int c)
  108. {
  109.     if(bufp >= BUFSIZE)
  110.         printf("ungetch: too many characters\n");
  111.     else
  112.         buf[bufp++] = c;
  113. }
  114.  
  115. /* dcl: parse a declarator */
  116. void dcl(void)
  117. {
  118.     int ns;
  119.  
  120.     for(ns=0; gettoken() == '*'; ) /* count *'s */
  121.         ns++;
  122.     dirdcl();
  123.     while(ns-- > 0)
  124.         strcat(out, " pointer to");
  125. }
  126.  
  127. /* dirdcl: parse a direct declarator */
  128. void dirdcl(void)
  129. {
  130.     int type;
  131.  
  132.     if(tokentype=='(') {         /* ( dcl ) */
  133.         dcl();
  134.         if(tokentype!=')')
  135.             printf("error: missing )\n");
  136.     } else if(tokentype == NAME) /* variable name */
  137.         strcpy(name, token);
  138.     else
  139.         printf("error: expected name or (dcl)\n");
  140.     while((type=gettoken())==PARENS || type == BRACKETS) {
  141.         if(type==PARENS)
  142.             strcat(out, " function returning");
  143.         else {
  144.             strcat(out, " array");
  145.             strcat(out, token);
  146.             strcat(out, " of");
  147.         }
  148.     }
  149. }
  150.  
  151. void clearbuffs(void)
  152. {
  153.     int i;
  154.     lastchar=0;
  155.     for(i=0; name[i]!='\0'; )
  156.         name[i++] = '\0';
  157.     for(i=0; token[i]!='\0'; )
  158.         token[i++] = '\0';
  159.     for(i=0; datatype[i]!='\0'; )
  160.         datatype[i++] = '\0';
  161.     for(i=0; out[i]!='\0'; )
  162.         out[i++] = '\0';
  163.     while(bufp>0)
  164.         buf[bufp--]='\0';
  165.     tokentype='\n';
  166. }
Advertisement
Add Comment
Please, Sign In to add comment