Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * This program recieves a source code of a certain program and checks for imbalance brackets
- * Upon finding an error, the program will print to the stdout the line number,line content
- * and the mismatched bracket.
- * In order to handle brackets balance check, I've created a stack of characters that will hold
- * the opening brackets, and an additional variable called c_bracket to handle curly bracket
- * another array was created called line, that acts as a buffer. first reading the characters
- * to the line array and then running the checks.
- */
- #include <stdio.h>
- #include <string.h>
- void skipcomment(void);
- void skipstring(void);
- char getnext(void);
- void readline(void);
- int addbracket(char);
- void cleanstack(void);
- int validbrac(char ch);
- void printerr(char ch);
- char skipspace(void);
- void skipchar(void);
- #define MAXLINE 150
- #define COMMENT_START '/'
- #define NEW_LINE '\n'
- #define STRING '"'
- #define CHAR '\''
- enum {INVALID,START,VALID,IN_LINE};
- int main(){
- char c;
- while((c=getnext()) != EOF)
- switch(c){
- case STRING:
- skipstring();
- break;
- case CHAR:
- skipchar();
- break;
- case COMMENT_START:
- if((c=getnext()) == '*')
- skipcomment();
- break;
- case '{': case '(': case '[':
- if(!addbracket(c)) /* if there was an error adding the bracket,prints an error message */
- printerr(c);
- break;
- case '}': case ')': case ']':
- if(!validbrac(c))
- printerr(c);
- break;
- case NEW_LINE:
- if(!validbrac(c))
- printerr(c);
- cleanstack();
- break;
- }
- if(!validbrac(c)) /* upon EOF does a final check to see if all brackets were closed */
- printerr(c);
- return 0;
- }
- /* skipstring: skips the whole string in the buffer */
- void skipstring(){
- char c;
- while((c=getnext()) != '"')
- if(c=='\\' && (c=getnext()) == '"') /* incase of an escape sequence of ", ignores it and continue with the loop */
- continue;
- }
- /* skipcomment: skips comments in the c90 format */
- void skipcomment(){
- char c;
- while((c=getnext()) != EOF)
- if(c == '*'){
- while(c == '*') /* skip all asterisks */
- c = getnext();
- if(c == '/') /* if closed with an '/' thats the end of the comment */
- return;
- }
- }
- /* skipchar: skip whatever inside the character literals */
- void skipchar(){
- char c;
- while((c=getnext()) != '\'')
- if(c=='\\' && (c=getnext()) == '\'') /*incase of an escape sequence ',ignores it and continue with the loop */
- continue;
- }
- /* variable declarations */
- char line[MAXLINE+1]; /* acts as a buffer,holding one line at a time */
- int lineind = START;
- int linenum = 0; /* line number */
- /* getnext: return the next character in the buffer,incase buffer is empty or reached the maximum
- reads the next line */
- char getnext(){
- if(lineind == START || lineind>MAXLINE || line[lineind] == '\0')
- readline();
- return line[lineind++];
- }
- /* readline: reads a line to a buffer */
- void readline(){
- for(lineind = START ; lineind <= MAXLINE && (line[lineind] = getchar()) != '\n' && line[lineind] != EOF ; lineind++)
- ;
- line[++lineind] = '\0';
- lineind = START;
- linenum++;
- }
- /* skipspace: skip all spaces and tabs,returning the next character */
- char skipspace(){
- char c;
- while((c = getnext()) ==' ' || c == '\t')
- ;
- lineind--; /* since the loop only stops once it read too much, indexing 1 step back */
- return c;
- }
- /* printerr: prints an error message based on the character passed */
- void printerr(char ch){
- if(ch == EOF)
- printf("Program ended : please notice some brackets were left unclosed\n");
- else if(ch == NEW_LINE)
- printf("an error occured at line %d:%s bracket left unclosed\n",linenum,line);
- else
- printf("an error occured at line %d column %d:%s please examine %c\n",linenum,lineind-1,line,(char)ch);
- }
- /* variable declaration */
- char brackstack[MAXLINE]; /* a stack that holds the opening square and round brackets */
- int braind = START;
- int c_bracket = 0; /* holds the amount of curly brackets */
- /* addbracket: adds the bracket to the stack as the closing version of it
- incase of a curly bracket, checks if it's a valid curly bracket
- meaning after it comes a newline. returns a non-zero for true
- and INVALID for false */
- int addbracket(char brack){
- if(brack == '[')
- return brackstack[braind++] = ']';
- else if(brack == '(')
- return brackstack[braind++] = ')';
- else if(brack == '{')
- return skipspace() == NEW_LINE?++c_bracket:INVALID;
- else
- return INVALID;
- }
- /* validbrac: validate if the brackets are balanced based on the character passed
- return true if the brackets are balanced false otherwise */
- int validbrac(char ch){
- if(braind<START && ch != '\n' && ch != EOF){ /* more closing brackets than opening ones while traversing line */
- braind = START;
- return INVALID;
- }
- switch(ch){
- case ']': case ')':
- return ch==brackstack[--braind]?VALID:INVALID;
- case '}':
- if(c_bracket>0) /* if it has a matching opening bracket */
- return c_bracket--;
- else
- return c_bracket = 0;
- case NEW_LINE: /* incase of a newline check to see of all square and round brackets were closed */
- return braind <= START; /* less than or equal to start is valid,since it means error messages were printed
- and no need for additional error message */
- case EOF:
- return braind <= START && c_bracket == 0; /* incase of EOF check to see of all brackets were closed */
- default:
- return INVALID;
- }
- }
- /* cleanstack: set the bracket stack to the start */
- void cleanstack(){
- braind = START;
- brackstack[braind] = '\0';
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement