/* * PARSER FOR THE * ====== === === * * DATA DECLARATION BUILDER * ==== =========== ======= * * This module is the parser used to interprete the high * level data declarations. * ******* Grammar for Declarations * * declns = ne-list( decln ) tEOF * decln = tID tEQ shapes tSEMI * shapes = ne-sep-list( shape, tOR ) * shape = tID [ tOPENBR params tCLOSEBR ] printlist * params = ne-sep-list( param, tCOMMA ) * param = tID tID * printlist = list( tSTR | tNUM ) */ #include <dcw.h> #include "struct.h" #include "lexer.h" #include "parser.h" #ifdef HASPROTOS static BOOL parse_decln( char ** , shapelist * ); static BOOL parse_shapes( shapelist * ); static BOOL parse_shape( char ** , paramlist *, printlist * ); static BOOL parse_params( paramlist * ); static BOOL parse_param( char ** , char ** ); static BOOL parse_printlist( printlist * ); static BOOL parse_printitem( printitem * ); #else static BOOL parse_decln(); static BOOL parse_shapes(); static BOOL parse_shape(); static BOOL parse_params(); static BOOL parse_param(); static BOOL parse_printlist(); static BOOL parse_printitem(); #endif /* declns = ne-list( decln ) tEOF */ BOOL parse_declns( dp ) declnlist *dp; { char *name; shapelist shapes; for(;;) { if( ! parse_decln( &name, &shapes ) ) return FALSE; *dp = build_declnlist( name, shapes, NULL ); if( nexttok() == tEOF ) break; ungettok(); dp = &( (*dp)->next ); } return TRUE; } static void expected( s ) char *s; { fprintf( stderr, "%s expected at line %d\n", s, lineno ); } #define MUSTBE(t,mesg) if( nexttok() != (t) ) {expected(mesg); return FALSE;} /* decln = tID tEQ shapes tSEMI */ static BOOL parse_decln( name, shapes ) char **name; shapelist *shapes; { MUSTBE( tID, "declaration" ); COPYOF( *name, lexidval ); MUSTBE( tEQ, "'='" ); if( ! parse_shapes( shapes ) ) return FALSE; MUSTBE( tSEMI, "';'" ); return TRUE; } /* shapes = ne-sep-list( shape, tOR ) */ static BOOL parse_shapes( sp ) shapelist *sp; { char *tagname; paramlist paras; printlist print; for(;;) { if( ! parse_shape( &tagname, ¶s, &print ) ) return FALSE; *sp = build_shapelist( tagname, paras, print, NULL ); if( nexttok() != tOR ) break; sp = &( (*sp)->next ); } ungettok(); return TRUE; } /* shape = tID [ tOPENBR params tCLOSEBR ] printlist */ static BOOL parse_shape( tagname, pl, print ) char **tagname; paramlist *pl; printlist *print; { *pl = NULL; *print = NULL; MUSTBE( tID, "shape name" ); COPYOF( *tagname, lexidval ); if( nexttok() == tOPENBR ) { if( ! parse_params( pl ) ) return FALSE; MUSTBE( tCLOSEBR, "')'" ); } else { ungettok(); } return parse_printlist( print ); } /* params = ne-sep-list( param, tCOMMA ) */ static BOOL parse_params( pp ) paramlist *pp; { char *type; char *name; for(;;) { if( !parse_param( &type, &name ) ) return FALSE; *pp = build_paramlist( type, name, NULL ); if( nexttok() != tCOMMA ) break; pp = &( (*pp)->next ); } ungettok(); return TRUE; } /* printlist = list( printitem ) */ /* NB: Never fails, cos items are one token long */ static BOOL parse_printlist( pp ) printlist *pp; { printitem item; *pp = NULL; while( parse_printitem( &item ) ) { *pp = build_printlist( item, NULL ); pp = &( (*pp)->next ); } return TRUE; } /* printitem = tSTR | tNUM */ static BOOL parse_printitem( item ) printitem *item; { char *temp; switch( nexttok() ) { case tSTR: COPYOF( temp, lexidval ); *item = build_printitem_str( temp ); return TRUE; case tNUM: *item = build_printitem_num( lexintval ); return TRUE; default: ungettok(); return FALSE; } } /* param = tID tID */ static BOOL parse_param( type, name ) char **type, **name; { MUSTBE( tID, "Field type" ); COPYOF( *type, lexidval ); MUSTBE( tID, "Field name" ); COPYOF( *name, lexidval ); return TRUE; }