/* cctr2.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 cctr2.y 2) Compile the bison output: gcc cctr2.tab.c -o cctr2 */ %{ 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 OTHER %start sourcecode %% sourcecode : /* empty */ | sourcecode declaration | sourcecode definition ; seqother : /*empty*/ | seqother OTHER ; 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( "cctr2(%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'; } /* Discriminate only between: identifier { } ( ) ; anything else */ if ( buf[0] == 'I' ) { name_t tmp; strncpy( tmp.buf, buf+1, NAMESZ-1 ); yylval = tmp; return ID; } else if ( buf[0] == ';' || buf[0] == '{' || buf == '}' || buf[0] == '(' || buf[0] == ')' ) { return buf[0]; } else { return OTHER; } }