%{
/*
....[@@@..[@@@..............[@.................. 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);
}