Advertisement
naorzr

Untitled

Apr 9th, 2017
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.27 KB | None | 0 0
  1. /*
  2.  * This program recieves a source code of a certain program and checks for imbalance brackets
  3.  * Upon finding an error, the program will print to the stdout the line number,line content
  4.  * and the mismatched bracket.
  5.  * In order to handle brackets balance check, I've created a stack of characters that will hold
  6.  * the opening brackets, and an additional variable called c_bracket to handle curly bracket
  7.  * another array was created called line, that acts as a buffer. first reading the characters
  8.  * to the line array and then running the checks.
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13.  
  14. void skipcomment(void);
  15. void skipstring(void);
  16. char getnext(void);
  17. void readline(void);
  18. int addbracket(char);
  19. void cleanstack(void);
  20. int validbrac(char ch);
  21. void printerr(char ch);
  22. char skipspace(void);
  23. void skipchar(void);
  24.  
  25. #define MAXLINE 150
  26. #define COMMENT_START '/'
  27. #define NEW_LINE '\n'
  28. #define STRING '"'
  29. #define CHAR '\''
  30.  
  31. enum {INVALID,START,VALID,IN_LINE};
  32.  
  33.  
  34. int main(){
  35.     char c;
  36.  
  37.     while((c=getnext()) != EOF)
  38.         switch(c){
  39.             case STRING:
  40.                 skipstring();
  41.                 break;
  42.  
  43.             case CHAR:
  44.                 skipchar();
  45.                 break;
  46.  
  47.             case COMMENT_START:
  48.                 if((c=getnext()) == '*')
  49.                     skipcomment();
  50.                 break;
  51.  
  52.             case '{': case '(': case '[':
  53.                 if(!addbracket(c))      /* if there was an error adding the bracket,prints an error message */
  54.                     printerr(c);
  55.                 break;
  56.  
  57.             case '}': case ')': case ']':
  58.                 if(!validbrac(c))
  59.                     printerr(c);
  60.                 break;
  61.  
  62.             case NEW_LINE:
  63.                 if(!validbrac(c))
  64.                     printerr(c);
  65.                 cleanstack();
  66.                 break;
  67.         }
  68.  
  69.     if(!validbrac(c))       /* upon EOF does a final check to see if all brackets were closed */
  70.         printerr(c);
  71.  
  72.     return 0;
  73. }
  74.  
  75. /* skipstring: skips the whole string in the buffer */
  76. void skipstring(){
  77.     char c;
  78.     while((c=getnext()) != '"')
  79.         if(c=='\\' && (c=getnext()) == '"')     /* incase of an escape sequence of ", ignores it and continue with the loop */
  80.             continue;
  81. }
  82.  
  83. /* skipcomment: skips comments in the c90 format */
  84. void skipcomment(){
  85.     char c;
  86.     while((c=getnext()) != EOF)
  87.         if(c == '*'){
  88.             while(c == '*')     /* skip all asterisks */
  89.                 c = getnext();
  90.             if(c == '/')      /* if closed with an '/' thats the end of the comment */
  91.                 return;
  92.         }
  93. }
  94.  
  95. /* skipchar: skip whatever inside the character literals */
  96. void skipchar(){
  97.     char c;
  98.     while((c=getnext()) != '\'')
  99.         if(c=='\\' && (c=getnext()) == '\'')        /*incase of an escape sequence ',ignores it and continue with the loop */
  100.             continue;
  101. }
  102.  
  103. /* variable declarations */
  104. char line[MAXLINE+1];       /* acts as a buffer,holding one line at a time */
  105. int lineind = START;
  106. int linenum = 0;        /* line number */
  107.  
  108.  
  109. /* getnext: return the next character in the buffer,incase buffer is empty or reached the maximum
  110.             reads the next line */
  111. char getnext(){
  112.     if(lineind == START || lineind>MAXLINE || line[lineind] == '\0')
  113.         readline();
  114.     return line[lineind++];
  115. }
  116.  
  117. /* readline: reads a line to a buffer */
  118. void readline(){
  119.     for(lineind = START ; lineind <= MAXLINE && (line[lineind] = getchar()) != '\n' && line[lineind] != EOF ; lineind++)
  120.         ;
  121.     line[++lineind] = '\0';
  122.     lineind = START;
  123.     linenum++;
  124. }
  125.  
  126. /* skipspace: skip all spaces and tabs,returning the next character */
  127. char skipspace(){
  128.     char c;
  129.     while((c = getnext()) ==' ' || c == '\t')
  130.         ;
  131.     lineind--;      /* since the loop only stops once it read too much, indexing 1 step back */
  132.     return c;
  133. }
  134.  
  135. /* printerr: prints an error message based on the character passed */
  136. void printerr(char ch){
  137.     if(ch == EOF)
  138.         printf("Program ended : please notice some brackets were left unclosed\n");
  139.     else if(ch == NEW_LINE)
  140.         printf("an error occured at line %d:%s  bracket left unclosed\n",linenum,line);
  141.     else
  142.         printf("an error occured at line %d column %d:%s  please examine %c\n",linenum,lineind-1,line,(char)ch);
  143. }
  144.  
  145. /* variable declaration */
  146. char brackstack[MAXLINE];       /* a stack that holds the opening square and round brackets */
  147. int braind = START;
  148. int c_bracket = 0;      /* holds the amount of curly brackets */
  149.  
  150. /* addbracket: adds the bracket to the stack as the closing version of it
  151.                 incase of a curly bracket, checks if it's a valid curly bracket
  152.                 meaning after it comes a newline. returns a non-zero for true
  153.                 and INVALID for false */
  154.  
  155. int addbracket(char brack){
  156.  
  157.     if(brack == '[')
  158.         return brackstack[braind++] = ']';
  159.     else if(brack == '(')
  160.         return brackstack[braind++] = ')';
  161.     else if(brack == '{')
  162.         return skipspace() == NEW_LINE?++c_bracket:INVALID;
  163.     else
  164.         return INVALID;
  165. }
  166.  
  167. /* validbrac: validate if the brackets are balanced based on the character passed
  168.             return true if the brackets are balanced false otherwise */
  169. int validbrac(char ch){
  170.  
  171.     if(braind<START && ch != '\n' && ch != EOF){        /* more closing brackets than opening ones while traversing line */
  172.         braind = START;
  173.         return INVALID;
  174.     }
  175.     switch(ch){
  176.         case ']': case  ')':
  177.             return ch==brackstack[--braind]?VALID:INVALID;
  178.         case '}':
  179.             if(c_bracket>0)     /* if it has a matching opening bracket */
  180.                 return c_bracket--;
  181.             else
  182.                 return c_bracket = 0;
  183.  
  184.         case NEW_LINE:      /* incase of a newline check to see of all square and round brackets were closed */
  185.             return braind <= START;     /* less than or equal to start is valid,since it means error messages were printed
  186.                                             and no need for additional error message */
  187.         case EOF:
  188.             return braind <= START && c_bracket == 0;       /* incase of EOF check to see of all brackets were closed */
  189.         default:
  190.             return INVALID;
  191.     }
  192.  
  193. }
  194.  
  195. /* cleanstack: set the bracket stack to the start */
  196. void cleanstack(){
  197.     braind = START;
  198.     brackstack[braind] = '\0';
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement