/* test1.y MR 20/09/98 Input file to 'bison' (or 'yacc'). Specification for AN UTTERLY SIMPLE PARSER, with pieces looted from the examples the gnu Linux files 'bison.info-1' and 'bison.info-2'. The input stream to the parser is a C-like source code, but with each identifier, operator, numeral, keyword, etc. occupying only ONE character. Type names are not used. Literals are not used, neither numerical, character or string. All identifier names are lower-case characters. There are no built-in language keywords, and no constructs like "while", "if", etc. An example input: Comment (not part of input): k; Declaration of global variable 'k' f(a,b); Declaration of function 'f' which takes the two parameters 'a' and 'b' m() Start of definition of function 'm' { i; j; i=f(j,j+k); Call of function 'f' } End of definition of function 'm' For easy testing by entering the input from the keyboard, blanks in the input are ignored and may occur anywhere in the input. How to generate the parser program: 1) Run bison on this file: bison test1.y 2) Compile the bison output: gcc test1.tab.c -o parsetest1 */ %{ #define YYSTYPE char char GLOBfname = 0x00; %} %token ID %token OP %start sourcecode %% sourcecode : /* empty */ | sourcecode declaration | sourcecode definition ; definition : ID ';' { printf( "globalvar-def %c\n", $1 ); } | ID '(' formalParList ')' '{' { printf( "func-def-begin %c\n", $1 ); GLOBfname = $1; } body '}' { printf( "func-def-end %c\n", $1 ); GLOBfname = 0x00; } ; declaration : ID '(' formalParList ')' ';' { printf( "func-decl %c\n", $1 ); } ; formalParList : /*empty*/ | nonemptyFPlist ; nonemptyFPlist : ID | nonemptyFPlist ',' ID ; body : /*empty*/ | body stmt ; stmt : ';' | expr ';' ; expr : atom | expr OP atom ; atom : ID | funccall | '(' expr ')' ; funccall : ID '(' actualParList ')' { printf( "func-call %c in function %c\n", $1, GLOBfname ); } ; actualParList : /*empty*/ | nonemptyAPlist ; nonemptyAPlist : expr | nonemptyAPlist ',' expr ; %% #if 0 | OP expr | expr '[' expr ']' | '(' ID ')' expr /*type cast*/ #endif #include main() { yyparse(); } yyerror( char * str ) { printf( "parsetest1: %s\n", str ); } int yylex( void ) { int ic; while ( ic = getchar(), ic == ' ' || ic == '\t' || ic == '\n' ) { ; } if ( ic == EOF ) { return 0; } else if ( 'a' <= ic && ic <= 'z' ) { yylval = (char)ic; return ID; } else if ( ic == '+' || ic == '-' || ic == '=' || ic == '*' || ic == '/' || ic == '.' ) { return OP; } else { return ic; } }