/* ccalltr1.y MR 20/09/98 Input file to 'bison' (or 'yacc') to generate a parser that parses the output ascii file as generated by running '../lexan/clscanc1.sh' on a C source file, and produces a calling tree as output (= which function calls which function). How to generate the parser program: 1) Run bison on this file: bison ccalltr1.y 2) Compile the bison output: gcc ccalltr1.tab.c -o ccalltr1 */ %{ int GLOBlinenr = 0; #define NAMESZ 40 typedef struct { char buf[NAMESZ]; } name_t; name_t GLOBfname; name_t GLOBnullname; #define YYSTYPE name_t %} %token ID %token OP %start sourcecode %% sourcecode : /* empty */ | sourcecode declaration | sourcecode definition ; /* * HxxxH matches everything from a '(' to the matching ')' : */ HxxxH : '(' xyz ')' ; xyz : /*empty*/ | xyz xatom ; xatom : anythx | HxxxH ; anythx : OP /* Anything except '(' ')' '{' '}' ';' '=' */ | ID | '*' | '[' | ']' | ',' ; type : ID | type ID | type '*' ; arrdecl : /*empty*/ | '[' ']' ; initializer : /*empty*/ | '=' ID /* "= value" */ | '=' OP ID /* "= -value" */ | '=' '{' valuelist '}' ; valuelist : ID | OP ID /* "-value" */ | valuelist ',' ID | valuelist ',' OP ID /* ", -value" */ | valuelist ',' '{' valuelist '}' ; definition : type ID arrdecl initializer ';' { name_t tmp = $2; printf( "globalvar-def '%s'\n", tmp.buf ); } | type ID HxxxH '{' { name_t tmp = $2; printf( "func-def-begin '%s'\n", tmp.buf ); GLOBfname = tmp; } body '}' { name_t tmp = $1; printf( "func-def-end '%s'\n", tmp.buf ); GLOBfname = GLOBnullname; } ; declaration : type ID '(' formalParList ')' ';' { name_t tmp = $2; printf( "func-decl '%s'\n", tmp.buf ); } ; formalParList : /*empty*/ | nonemptyFPlist ; nonemptyFPlist : type ID | nonemptyFPlist ',' type ID ; body : /*empty*/ | body stmt ; stmt : ';' | expr ';' ; expr : atom | expr OP atom ; atom : ID | funccall | '(' expr ')' ; funccall : ID '(' actualParList ')' { name_t tmp = $1; printf( "func-call '%s' in function '%s'\n", tmp.buf, GLOBfname.buf ); } ; actualParList : /*empty*/ | nonemptyAPlist ; nonemptyAPlist : expr | nonemptyAPlist ',' expr ; %% #if 0 | OP expr | expr '[' expr ']' | '(' ID ')' expr /*type cast*/ #endif #include #include main() { strcpy( GLOBnullname.buf, "null" ); GLOBfname = GLOBnullname; yyparse(); } yyerror( char * str ) { printf( "ccalltr1(%d): %s\n", GLOBlinenr, str ); } #define BUFSZ 256 int yylex( void ) { char buf[BUFSZ]; int len; if ( GLOBlinenr++, ! fgets( buf, sizeof(buf), stdin ) ) { return 0; /* At EOF */ } len = strlen( buf ); if ( buf[len-1] == '\n' ) { buf[len-1] = '\0'; } if ( buf[0] == 'I' || buf[0] == 'K' || buf[0] == 'T' || buf[0] == 'M' || buf[0] == 'D' || buf[0] == 'N' || buf[0] == 'C' || buf[0] == 'S' ) { name_t tmp; strncpy( tmp.buf, buf+1, NAMESZ-1 ); yylval = tmp; return ID; } else if ( buf[0] == '+' ) { if ( buf[1] == '*' ) { return '*'; } else if ( buf[1] == '=' ) { return '='; } else { return OP; } } else { return buf[0]; } }