%{ /* ....[@@@..[@@@..............[@.................. MUD++ is a written from ....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and ....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++. ....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing ....[@......[@..[@@@@@..[@@@@@.................. development project. All ................................................ contributions are welcome. ....Copyright(C).1995.Melvin.Smith.............. Enjoy. ------------------------------------------------------------------------------ Melvin Smith (aka Fusion) msmith@hom.net MUD++ development mailing list mudpp-list@mailhost.net ------------------------------------------------------------------------------ yacc.y Compiler grammar for MUDC Compiles to intermediate MUDAsm (see docs/vm) */ #include "sym.h" #include "parse.h" extern sym * sym_tab[]; extern char yytext[]; char id[ 256 ]; long line; %} %union { long lval; float fval; char * sval; sym * sym_ptr; node * node_ptr; } %type <lval> type_specifier %type <node_ptr> declaration %type <sym_ptr> declarator %type <sym_ptr> init_declarator %type <sym_ptr> init_declarator_list %type <node_ptr> declaration_list %type <sym_ptr> parameter_type_list %type <sym_ptr> parameter_declaration %type <node_ptr> statement %type <node_ptr> statement_list %type <node_ptr> compound_statement %type <node_ptr> jump_statement %type <node_ptr> function_call %type <node_ptr> function_def %type <node_ptr> primary_expression %type <node_ptr> assignment_expression %type <node_ptr> postfix_expression %type <node_ptr> unary_expression %token <sym_ptr> ID %token <lval> CONSTANT_INT %token <fval> CONSTANT_FLOAT %token <sval> STRING_LITERAL %token DEC_OP INC_OP %token VOID INT STRING %token RETURN %start unit %% unit: function_def {} | unit function_def {} ; declarator: ID { $$ = $1; } | ID '(' ')' { $$ = $1; } | ID '(' parameter_type_list ')' { $$ = $1; $$->next = $3; } ; type_specifier: VOID { $$ = TYPE_VOID; } | INT { $$ = TYPE_INT; } | STRING { $$ = TYPE_STRING; } ; declaration: type_specifier init_declarator_list ';' { /* $1 = lval (int), $2 = sym_ptr (symbol *) */ node * id = mkleaf_declaration( $1, $2 ); $$ = id; printf( "declaration\n" ); } ; init_declarator_list: init_declarator { $$ = $1; } | init_declarator_list ',' init_declarator { $1->next = $3; $$ = $1; } ; init_declarator: declarator { $$ = $1; } | declarator '=' initializer { $$ = $1; } ; initializer: ; declaration_list: declaration | declaration_list declaration { $$ = $1; $$->right = $2; } ; parameter_type_list: parameter_declaration { $$ = $1; } | parameter_type_list ',' parameter_declaration { $$->next = $3; } ; parameter_declaration: type_specifier declarator { mk_type( $1, $2 ); $$ = $2; } ; compound_statement: '{' '}' { $$ = 0; } | '{' statement_list '}' { $$ = $2; printf( "statement list\n" ); } | '{' declaration_list '}' { $$ = $2; printf( "dec list\n" ); } | '{' declaration_list statement_list '}' { $$ = add_leaf_right( $2, $3 ); } ; statement_list: statement { $$ = $1; } | statement_list statement { $$ = $1; $$->right = $2; } statement: postfix_expression ';' { $$ = $1; } | assignment_expression ';' | jump_statement { printf( "jump statement\n" ); } | ';' { $$ = (node *)0; } ; jump_statement: RETURN ';' {} | RETURN ID ';' {} | RETURN unary_expression ';' {} ; function_def: type_specifier declarator compound_statement { printf( "function def with args\n" ); $$ = mkleaf_function_def( $1, $2, $3 ); add_tree( $$ ); } ; function_call: ID '(' ')' { node * id = mknode( OP_CALL, $1, 0, 0 ); $$ = id; printf( "function call\n" ); } ; primary_expression: CONSTANT_INT { } | STRING_LITERAL { } | ID { } ; postfix_expression: primary_expression { } | function_call { $$ = $1; } | postfix_expression '[' primary_expression ']' | postfix_expression '.' postfix_expression | postfix_expression INC_OP | postfix_expression DEC_OP ; unary_expression: postfix_expression | INC_OP unary_expression {} | DEC_OP unary_expression {} ; assignment_expression: unary_expression assignment_op assignment_expression ; assignment_op: '=' ; %% #include <stdio.h> extern FILE *yyin; int main( int argc, char * argv[] ) { if( argc > 1 ) { if( !( yyin = fopen( argv[1], "r" ) ) ) { printf( "Error reading source file %s.\n", argv[1] ); exit(0); } } else { printf( "No source file specified.\n" ); exit(0); } init_sym_tab(); yyparse(); fclose( yyin ); dump_sym_tab(); printf( "Generating MUDAsm.\n" ); emit_asm(); } int yyerror( char * s ) { printf( "(error) line %d: %s\n", line, s ); printf( "Didn't create output asm.\n" ); exit(0); }