%{ #include #include #define FDEFN 257 #define FCALL 258 int fdefn = 0, fcall = 0, lineno = 1; char *lexeme; char **fname; %} whitespace [ \t]+ optwhitespace [ \t]* validname [a-zA-Z_][a-zA-Z0-9_]* invalidname (if|for|while|switch|return) invalidtype (else|do) leftparen {optwhitespace}\( ftypename {validname}{whitespace}\*?{optwhitespace}{validname} %% {invalidtype}{whitespace}{invalidname}/{leftparen} { } {invalidtype}{whitespace}{validname}/{leftparen} { lexeme = yytext; while ((*lexeme != ' ') && (*lexeme != '\t')) ++lexeme; while ((*lexeme == ' ') || (*lexeme == '\t')) ++lexeme; return FCALL; } {ftypename}/{leftparen} { lexeme = yytext; return FDEFN; } {invalidname}/{leftparen} { } {validname}/{leftparen} { lexeme = yytext; return FCALL; } \n { ++lineno; } . { } %% int yywrap () { /* Finish the work for the last opened file */ fclose(yyin); printf("+++ %d function definitions found\n", fdefn); printf("+++ %d function calls found\n", fcall); /* No more files to read */ if (*fname == NULL) return 1; /* Open the next file and set yyin accordingly */ printf("\n\nProcessing input from %s\n", *fname); yyin = (FILE *)fopen(*fname,"r"); ++fname; /* Bookkeeping before yylex() resumes its patter-matching loop for the next file */ fdefn = fcall = 0; lineno = 1; return 0; } int main ( int argc, char *argv[] ) { int nexttoken; /* Open the first file */ if (argc == 1) { printf("\n\nProcessing input from stdin\n"); fname = argv + 1; /* NULL pointer */ } else { printf("\n\nProcessing input from %s\n", argv[1]); yyin = (FILE *)fopen(argv[1],"r"); fname = argv + 2; } /* Only one pattern-matching loop */ while ((nexttoken = yylex())) { switch (nexttoken) { case FCALL: printf("\t\tFunction call at line %d: \"%s\"\n", lineno, lexeme); ++fcall; break; case FDEFN: printf("\tFunction definition at line %d: \"%s\"\n", lineno, lexeme); ++fdefn; break; } } exit(0); }