9p / who / tweedy / 9C / 1
Exercise 1.24: Rudimentary Syntax Checker
Code
#include <u.h>
#include <libc.h>
#include <bio.h>
#define STDIN 0
/* rudimentary syntax error checker: unbalanced parentheses (, brackets [, and braces { */
void
main()
{
Biobuf *bstdin;
bstdin = Bfdopen(STDIN, OREAD);
int inquote, nest, oparens, obrackets, obraces, cparens, cbrackets, cbraces, error;
char c, prev, pprev;
inquote = nest = oparens = obrackets = obraces = cparens = cbrackets = cbraces = error = 0;
prev = Bgetc(bstdin);
pprev = '\0';
while((c = Bgetc(bstdin)) >= 0){
/* set states */
if(prev=='/' && c=='*'){
nest++;
}
else if(prev=='*' && c=='/'){
c = Bgetc(bstdin);
nest--;
}
else if((c=='\'' || c=='\"') && (prev!='\\' || (prev=='\\' && pprev=='\\'))){
if(inquote == 0){
nest++;
inquote = 1;
}
else{
nest--;
inquote = 0;
}
}
/* process state */
if(nest > 0)
;
else{
if(c=='(' && prev!='\\'){
oparens++;
}
if(c=='[' && prev!='\\'){
obrackets++;
}
if(c=='{' && prev!='\\'){
obraces++;
}
if(c==')' && prev!='\\'){
cparens++;
}
if(c==']' && prev!='\\'){
cbrackets++;
}
if(c=='}' && prev!='\\'){
cbraces++;
}
}
pprev = prev;
prev = c;
}
if(oparens != cparens){
print("SYNTAX ERROR: Mismatched parentheses: %d open, %d closed.\n", oparens, cparens);
error = 1;
}
if(obrackets != cbrackets){
print("SYNTAX ERROR: Mismatched brackets: %d open, %d closed.\n", obrackets, cbrackets);
error = 1;
}
if(obraces != cbraces){
print("SYNTAX ERROR: Mismatched braces: %d open, %d closed.\n", obraces, cbraces);
error = 1;
}
if(error == 0)
print("No sytanx errors found.\n");
exits(0);
}
/* some tests; the compiler recognizes // comments and this program does not */
// }
// )
// ]
// ")" <- this one should not register
// ']' <- neither should this one
Output
$ 9c syntax.c; 9l syntax.o -o syntax
$ ./syntax < syntax.c
SYNTAX ERROR: Mismatched parentheses: 30 open, 31 closed.
SYNTAX ERROR: Mismatched brackets: 0 open, 1 closed.
SYNTAX ERROR: Mismatched braces: 17 open, 18 closed.
tweedy