/* paragrafo 1.9 pagina 31 esercizio 1.24 Rileva grossolani errori di sintassi dei programmi in C, per esempio l'incoerenza fra parentesi (tonde, quadre e graffe) aperte e chiuse. Non tralascia gli apici e le virgolette, le sequenze di controllo e i commenti. */ #include <stdio.h> #define SI 1 #define NO 0 #define MAXPAR 1000 /* numero massimo di parentesi aperte */ int toggle(int); int remark_remove(char []); int main() { int c1, c2, i, nl, par_err; int car_flag = NO; int str_flag = NO; int esc_flag = NO; char par_vec[MAXPAR]; char next_from_remark[1]; for (i = 0; i < MAXPAR; ++i) par_vec[i] = '\0'; i = 0; nl = 0; par_err = 0; if ((c1 = getchar()) != EOF) { ++nl; while ((c2 = getchar()) != EOF) { /* car_flag e str_flag discriminano se e' o non e' LITERAL */ if (c1 == '"' && car_flag == NO) if (esc_flag == NO) str_flag = toggle(str_flag); else esc_flag = NO; else if (c1 == '\'' && str_flag == NO) if (esc_flag == NO) car_flag = toggle(car_flag); else esc_flag = NO; else if (c1 == '\\' && (str_flag == SI || car_flag == SI)) esc_flag = toggle(esc_flag); else esc_flag = NO; /* rimozione dei commenti */ if (c1 == '/' && c2 == '*' && car_flag == NO && str_flag == NO) { nl = nl + remark_remove(next_from_remark); c1 = next_from_remark[0]; } else { /* verifica delle parentesi */ if (car_flag == NO && str_flag == NO) if ((c1 == '{' || c1 == '[' || c1 == '(') && par_err == NO) { par_vec[i] = c1; ++i; } else if ((c1 == '}' || c1 == ']' || c1 == ')') && par_err == NO) if (--i < 0) par_err = nl; else if (c1 == '}') if (par_vec[i] != '{') par_err = nl; else par_vec[i] = '\0'; else if (c1 == ']') if (par_vec[i] != '[') par_err = nl; else par_vec[i] = '\0'; else if (c1 == ')') if (par_vec[i] != '(') par_err = nl; else par_vec[i] = '\0'; putchar(c1); /* incrementa e scrive i numeri di riga di programma */ if (c1 == '\n') printf("%3d:: ", ++nl); c1 = c2; } } } if (c1 != EOF) putchar(c1); if (c1 != '\n') putchar('\n'); if (i < 0) printf("TROPPE PARENTESI CHIUSE\n"); else if (i > 0) printf("CHIUDERE LE PARENTESI \"%s\"\n", par_vec); if (par_err != 0) printf("ERRORE DI PARENTESI ALLA RIGA %d\n", par_err); if (car_flag == SI) printf("APICI DISPARI\n"); if (str_flag == SI) printf("VIRGOLETTE DISPARI\n"); return 0; } int toggle(int status) { if (status == NO) return SI; else return NO; } int remark_remove(char c[]) { int star, slash, newline; newline = 0; if ((star = getchar()) != EOF) while ((slash = getchar()) != EOF) if (star == '*' && slash == '/') { c[0] = getchar(); return newline; } else { if (star == '\n') ++newline; star = slash; } c[0] = '\a'; return newline; }