%{ CODE HEADER /* * The Termprocessor Kimwitu * * Copyright (c) 1991 University of Twente, Dept TIOS. * All rights reserved. * */ %} /* * parse.k */ %{ #if ! (defined(lint) || defined(SABER) || defined(CODECENTER)) static char parse_kAccesSid[] = "@(#)$Id: parse.k,v 1.18 1998/01/27 16:57:25 belinfan Rel $"; #endif %} /***************************************************************************/ %{ KC_TYPES_HEADER extern int pg_lineno; /* global line # */ extern int pg_column; /* global column # */ extern int pg_charpos; /* global charpos # */ extern casestring pg_filename; /* global file name */ extern int pg_no_of_arguments; /* no_of_arguments */ extern phylumdeclarations Thephylumdeclarations; /* global phylumdecls */ extern rwdeclarations Therwdeclarations; /* global rw-decls */ extern fndeclarations Thefndeclarations; /* fn-decls for the file being parsed */ extern fnfiles Thefnfiles; /* global fn-decls */ extern includefiles Theincludefiles; /* global incl-decls */ extern unparsedeclarations Theunparsedeclarations; /* global unp-decls */ extern argsnumbers Theargsnumbers; /* global list of argsnumbers */ extern viewnames Theuviewnames; /* global list of u-viewnames */ extern viewnames Therviewnames; /* global list of r-viewnames */ extern storageclasses Thestorageclasses; /* global list of storageclasses */ extern boolean pg_uviewshavebeendefined; /* global indication */ extern boolean pg_rviewshavebeendefined; /* global indication */ extern boolean pg_storageclasseshavebeendefined; /* global indication */ %} %{ int pg_lineno = 1; /* global line # */ int pg_column = 0; /* global column # */ int pg_charpos = 0; /* global charpos # */ casestring pg_filename; /* global file name */ int pg_no_of_arguments; /* no_of_arguments */ phylumdeclarations Thephylumdeclarations; /* global phylumdecls */ rwdeclarations Therwdeclarations; /* global rw-decls */ fndeclarations Thefndeclarations; /* fn-decls for the file being parsed */ fnfiles Thefnfiles; /* global fn-decls */ includefiles Theincludefiles; /* global incl-decls */ unparsedeclarations Theunparsedeclarations; /* global unp-decls */ argsnumbers Theargsnumbers; /* global list of argsnumbers */ viewnames Theuviewnames; /* global list of u-viewnames */ viewnames Therviewnames; /* global list of r-viewnames */ storageclasses Thestorageclasses; /* global list of storageclasses */ boolean pg_uviewshavebeendefined; /* global indication */ boolean pg_rviewshavebeendefined; /* global indication */ boolean pg_storageclasseshavebeendefined; /* global indication */ %} /***************************************************************************/ %{ #include "util.h" %} phylumdeclarations mergephylumdeclarations( pd, pds ) phylumdeclaration pd; phylumdeclarations pds; { two_phyla tp; with( pd ) { PhylumDeclaration( pd_id, pd_stopt, pd_pb, pd_ccopt ): { phylumdeclaration fpd = f_lookupuserdecl( pd_id ); if (!fpd) { v_add( pd_id ); return Consphylumdeclarations( pd, pds ); } else if ( pd == fpd ) { if ( f_added( pd_id ) ) { return pds; } else { v_add( pd_id ); return Consphylumdeclarations( pd, pds ); } } else { with( fpd ) { PhylumDeclaration( fpd_id, fpd_stopt, fpd_pb, fpd_ccopt ): { with( tp = TwoStorageoption( pd_stopt, fpd_stopt ) ) { TwoStorageoption( *, NoStorageOption() ): { fpd->u.PhylumDeclaration.storageoption_1 = pd_stopt; } TwoStorageoption( NoStorageOption(), * ): { /*EMPTY*/ /* nothing to do... keep the old storageoption */ } TwoStorageoption( NegativeStorageOption( id ), NegativeStorageOption( id ) ): { /***EMPTY***/ KC_LINTUSE(id); /* nothing to do */ } TwoStorageoption( PositiveStorageOption( id ), PositiveStorageOption( id ) ): { /***EMPTY***/ KC_LINTUSE(id); /* nothing to do */ } TwoStorageoption( NegativeStorageOption( id ), PositiveStorageOption( id ) ): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1storageoption1S1ID( "storage option mismatch ( declared as ", fpd_stopt, ") for phylum", fpd_id ))); } TwoStorageoption( PositiveStorageOption( id ), NegativeStorageOption( id ) ): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1storageoption1S1ID( "storage option mismatch ( declared as ", fpd_stopt, ") for phylum", fpd_id ))); } TwoStorageoption( *, * ): { /* nothing to do, as long as we only have _one_ storage ID * as soon as we get more different storage ID's we need to keep a list of them. */ v_report(NonFatal( FileLine( pd_id->file, pd_id->line ), Problem1S1storageoption1S1ID( "storage option mismatch ( declared as ", fpd_stopt, ") for phylum", fpd_id ))); } } free_two_phyla( tp, False ); with( tp = TwoProductionblock( pd_pb, fpd_pb ) ) { TwoProductionblock( Emptyproductionblock(), Emptyproductionblock() ): { /*EMPTY*/ /* nothing to do... keep the old productionblock */ } TwoProductionblock( Emptyproductionblock(), * ): { /*EMPTY*/ /* nothing to do... keep the old productionblock */ } TwoProductionblock( ListAlternatives( *, * ), Emptyproductionblock() ): { fpd->u.PhylumDeclaration.productionblock_1 = pd_pb; } TwoProductionblock( ListAlternatives( *, * ), * ): { v_report(NonFatal( FileLine( pd_id->file, pd_id->line ), Problem1S1ID( "production block mismatch: trying to redefine list phylum", pd_id ))); } TwoProductionblock( PredefinedAlternatives( * ), Emptyproductionblock() ): { fpd->u.PhylumDeclaration.productionblock_1 = pd_pb; } TwoProductionblock( PredefinedAlternatives( * ), * ): { v_report(NonFatal( FileLine( pd_id->file, pd_id->line ), Problem1S1ID( "production block mismatch: trying to predefine phylum", pd_id ))); } TwoProductionblock( NonlistAlternatives( * ), Emptyproductionblock() ): { fpd->u.PhylumDeclaration.productionblock_1 = pd_pb; } TwoProductionblock( NonlistAlternatives( pd_pb_a ), NonlistAlternatives( fpd_pb_a ) ): { fpd_pb->u.NonlistAlternatives.alternatives_1 = concat_alternatives( pd_pb_a, fpd_pb_a ); } TwoProductionblock( NonlistAlternatives( * ), * ): { v_report(NonFatal( FileLine( pd_id->file, pd_id->line ), Problem1S1ID( "production block mismatch: trying to extend phylum", pd_id ))); } } free_two_phyla( tp, False ); with( tp = TwoCcode_option( pd_ccopt, fpd_ccopt ) ) { TwoCcode_option( CcodeOption( pd_ccopt_attr, pd_ccopt_ct ), CcodeOption( fpd_ccopt_attr, fpd_ccopt_ct )): { fpd->u.PhylumDeclaration.Ccode_option_1 = CcodeOption( concat_attributes( pd_ccopt_attr, fpd_ccopt_attr), concat_Ctexts( pd_ccopt_ct, fpd_ccopt_ct )); } } free_two_phyla( tp, False ); } } return pds; } } } } /***************************************************************************/ /* * build the correct list declarations from the list and the element phylum */ %{ #include "extocc.h" %} /* create kc_str_conc2, and MALLOC macros, if they don't already exist */ %{ #ifndef MALLOC # define MALLOC emalloc #endif #ifndef kc_str_conc2 # include # define kc_str_conc2(a,b) (char*)strcat(strcpy((char *) MALLOC((kc_size_t)(strlen(a) + strlen(b) +1)), a), b) #endif %} /* * build the correct list declarations from the list and the element phylum */ alternatives makeListAlternatives( listphylum, elementphylum ) ID listphylum; ID elementphylum; { ID Nil_id, Cons_id; alternative Nil_alternative, Cons_alternative; Nil_id = Id( Str( mkcasestring( kc_str_conc2("Nil",f_strofID(listphylum))))); Cons_id = Id( Str( mkcasestring( kc_str_conc2("Cons",f_strofID(listphylum))))); Nil_id->line = elementphylum->line; Nil_id->file = elementphylum->file; Cons_id->line = elementphylum->line; Cons_id->file = elementphylum->file; Nil_alternative = Alternative( Nil_id, Nilarguments() ); Cons_alternative = Alternative( Cons_id, Consarguments( listphylum, Consarguments( elementphylum, Nilarguments() ) ) ); v_extendoccur( Nil_id, ITUserOperator( Nil_alternative, listphylum ) ); v_extendoccur( Cons_id, ITUserOperator( Cons_alternative, listphylum ) ); return Consalternatives( Cons_alternative, Consalternatives( Nil_alternative, Nilalternatives() ) ); } /***************************************************************************/ char *f_strofID( id ) ID id; { with( id ) { Id( Str( cs ) ): { return cs->name; } } } /***************************************************************************/ phylumdeclaration f_lookupuserdecl( id ) ID id; { with( id ) { Id( uid ): { with( uid->type ) { ITUnknown(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "undefined phylum:", id ))); return 0; } ITPredefinedBigatomPhylum( * ), ITPredefinedPhylum( * ): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined phylum:", id ))); return 0; } ITUserPhylum( pd ): { return pd; } ITPredefinedOperator( *, * ): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined operator:", id ))); return 0; } ITUserOperator( *, * ): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined operator:", id ))); return 0; } ITPredefinedStorageClass(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined storage class:", id ))); return 0; } ITStorageClass(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined storage class:", id ))); return 0; } ITPredefinedUView(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined unparse view:", id ))); return 0; } ITUserUView(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined unparse view:", id ))); return 0; } ITPredefinedRView(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined rewrite view:", id ))); return 0; } ITUserRView(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined rewrite view:", id ))); return 0; } ITUserFunction( * ): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined function:", id ))); return 0; } } } } } phylumdeclaration f_lookupdecl( id ) ID id; { with( id ) { Id( uid ): { with( uid->type ) { ITUnknown(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "undefined phylum:", id ))); return 0; } ITPredefinedBigatomPhylum( pd ), ITPredefinedPhylum( pd ): { return pd; } ITUserPhylum( pd ): { return pd; } ITPredefinedOperator( *, * ): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined operator:", id ))); return 0; } ITUserOperator( *, * ): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined operator:", id ))); return 0; } ITPredefinedStorageClass(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined storage class:", id ))); return 0; } ITStorageClass(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined storage class:", id ))); return 0; } ITPredefinedUView(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined unparse view:", id ))); return 0; } ITUserUView(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined unparse view:", id ))); return 0; } ITPredefinedRView(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined rewrite view:", id ))); return 0; } ITUserRView(): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined rewrite view:", id ))); return 0; } ITUserFunction( * ): { v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined function:", id ))); return 0; } } } } } argsnumbers insert_in_argsnumbers( i, a ) int i; argsnumbers a; { with( a ) { Nilargsnumbers(): { return Consargsnumbers( i, a ); } Consargsnumbers( j, ra ): { if ( i < j ) { return Consargsnumbers( i, a ); } else if ( i == j ) { return a; } else { return Consargsnumbers( j, insert_in_argsnumbers( i, ra )); } } } } void set_includefiles( ifs, i ) includefiles ifs; includedeclaration i; { foreach( pl_includefile; includefiles ifs ) { /* SUPPRESS 622 */ assert((pl_includefile->inc_type == include_file) || (pl_includefile->inc_type == include_header)); pl_includefile->inc[(int)pl_includefile->inc_type] = Consincludedeclarations( i, pl_includefile->inc[(int)pl_includefile->inc_type] ); } } /***************************************************************************/ /* routines to help parsing of Ansi-C style function defs */ ID f_ID_of_declarator( $d ) ac_declarator d; { AcDeclarator( *, dd ): { return f_ID_of_direct_decl( dd ); } } static ID f_ID_of_direct_decl( $d ) ac_direct_declarator d; { AcDirectDeclId( i ): { return i; } AcDirectDeclPack( a_d ): { return f_ID_of_declarator( a_d ); } AcDirectDeclArray( a_d, * ): { return f_ID_of_direct_decl( a_d ); } AcDirectDeclProto( a_d, * ): { return f_ID_of_direct_decl( a_d ); } AcDirectDeclKandR( a_d, * ): { return f_ID_of_direct_decl( a_d ); } } /*********/ int f_stars_of_declarator( $d ) ac_declarator d; { AcDeclarator( po, * ): { return f_stars_of_ac_pointer_option( po ); } } static int f_stars_of_ac_pointer_option( $d ) ac_pointer_option d; { Nopointer(): { return 0; } Yespointer( p ): { return f_stars_of_ac_pointer( p ); } } static int f_stars_of_ac_pointer( $d ) ac_pointer d; { AcPointerNil( * ): { return 1; } AcPointerCons( *, p ): { return 1 + f_stars_of_ac_pointer( p ); } } /*********/ fnclass f_fnclass_info( $ds, fn ) ac_declaration_specifiers ds; casestring fn; { Nilac_declaration_specifiers(): { return GlobalFn(); } Consac_declaration_specifiers( h, t ): { if (f_static_in_ac_decl_spec( h )) { return LocalFn( fn ); } else { return f_fnclass_info( t, fn ); } } } static boolean f_static_in_ac_decl_spec( $ds ) ac_declaration_specifier ds; { AcDeclSpecStorageSpec( a_sc ): { return f_static_in_ac_stor_class( a_sc ); } AcDeclSpecTypeSpec( * ): { return False; } AcDeclSpecTypeQual( * ): { return False; } } static boolean f_static_in_ac_stor_class( $sc ) ac_storage_class_specifier sc; { AcAuto(): { return False; } AcRegister(): { return False; } AcStatic(): { return True; } AcExtern(): { return False; } AcTypedef(): { return False; } } /*********/ ID f_ID_of_ac_declaration_specifiers( $d ) ac_declaration_specifiers d; { Nilac_declaration_specifiers(): { return 0; } Consac_declaration_specifiers( h, t ): { ID tmp = f_ID_of_ac_declaration_specifier( h ); if (tmp) { return tmp; } else { return f_ID_of_ac_declaration_specifiers( t ); } } } static ID f_ID_of_ac_declaration_specifier( $d ) ac_declaration_specifier d; { AcDeclSpecStorageSpec( * ), AcDeclSpecTypeQual( * ): { return 0; } AcDeclSpecTypeSpec( t ): { return f_ID_of_ac_type_specifier( t ); } } static ID f_ID_of_ac_type_specifier( $d ) ac_type_specifier d; { AcTypeSpec( i ): { return i; } } /***************************************************************************/ void check_proto_ac_parameter_declaration( f, l, C_vardecls, $decl ) casestring f; int l; ac_declaration_list C_vardecls; ac_declarator decl; { AcDeclarator( *, add ): { with( add ) { AcDirectDeclId( * ), AcDirectDeclPack( * ), AcDirectDeclArray( *, * ), AcDirectDeclKandR( *, * ): {/*EMPTY*/} AcDirectDeclKandR( *, Consac_identifier_list( Id( Str( "void" )), Nilac_identifier_list() ) ), AcDirectDeclProto( *, * ): { with( C_vardecls ) { Nilac_declaration_list(): {/*EMPTY*/} Consac_declaration_list( *, * ): { v_report(Warning( FileLine( f, l ), Problem1S( "unexpected mix of non-ansi (old style) and ansi (prototype) function argument declaration" ))); } } } } } } /***************************************************************************/ void check_no_patternchaingroup_in_patternchain( f, l, $a_patternchain, ctxt ) casestring f; int l; patternchain a_patternchain; char *ctxt; { Conspatternchain( h, t ): { check_no_patternchaingroup_in_patternchain( f, l, t, ctxt ); with( h ) { PatternchainitemOutmost( * ), PatternchainitemDollarid( * ): {/*EMPTY*/} PatternchainitemGroup( * ): { v_report(NonFatal( FileLine( f, l ), Problem3S( "no pattern grouping () allowed in", ctxt, "context." ))); } } } Nilpatternchain(): {/*EMPTY*/} } void check_no_patternchaingroup_in_patternchains( f, l, $a_patternchains, ctxt ) casestring f; int l; patternchains a_patternchains; char *ctxt; { Conspatternchains( h, t ): { check_no_patternchaingroup_in_patternchains( f, l, t, ctxt ); check_no_patternchaingroup_in_patternchain( f, l, h, ctxt ); } Nilpatternchains(): {/*EMPTY*/} } /***************************************************************************/ void check_no_patternchaingroup_or_pattern_in_patternchain( f, l, $a_patternchain, ctxt ) casestring f; int l; patternchain a_patternchain; char *ctxt; { Conspatternchain( h, t ): { check_no_patternchaingroup_or_pattern_in_patternchain( f, l, t, ctxt ); with( h ) { PatternchainitemOutmost( op ): { /* check_no_pattern_in_outmostpattern( op ); */ } PatternchainitemDollarid( * ): {/*EMPTY*/} PatternchainitemGroup( * ): { v_report(NonFatal( FileLine( f, l ), Problem3S( "no pattern grouping () allowed in", ctxt, "context." ))); } } } Nilpatternchain(): {/*EMPTY*/} } void check_no_patternchaingroup_or_pattern_in_patternchains( f, l, $a_patternchains, ctxt ) casestring f; int l; patternchains a_patternchains; char *ctxt; { Conspatternchains( h, t ): { check_no_patternchaingroup_or_pattern_in_patternchains( f, l, t, ctxt ); check_no_patternchaingroup_or_pattern_in_patternchain( f, l, h, ctxt ); } Nilpatternchains(): {/*EMPTY*/} } /***************************************************************************/ patternchains syn_patternchains_fileline( patternchains $a_patternchains, casestring a_file, int a_line ) { Conspatternchains( h, t ): { (void)syn_patternchains_fileline( t, a_file, a_line ); (void)syn_patternchain_fileline( h, t->file, t->line ); $0->file = h->file; $0->line = h->line; return a_patternchains; } Nilpatternchains(): { $0->file = a_file; $0->line = a_line; return a_patternchains; } } patternchain syn_patternchain_fileline( patternchain $a_patternchain, casestring a_file, int a_line ) { Conspatternchain( h, t ): { (void)syn_patternchain_fileline( t, a_file, a_line ); $0->file = h->file; $0->line = h->line; return a_patternchain; } Nilpatternchain(): { $0->file = a_file; $0->line = a_line; return a_patternchain; } } /***************************************************************************/ /* generate unique variable names for the foreach variables generated for * the with-expression in a foreach or foreach-after context. */ withexpressions pf_gen_foreachwith_vars( idCexpressions a_idCexpressions ) { static int nrof_foreach_occ = 0; nrof_foreach_occ++; return t_pf_gen_foreachwith_vars(a_idCexpressions, nrof_foreach_occ, length_idCexpressions(a_idCexpressions), False); } withexpressions pf_gen_foreachwith_listvars( idCexpressions a_idCexpressions ) { static int nrof_foreach_occ = 0; nrof_foreach_occ++; return t_pf_gen_foreachwith_vars(a_idCexpressions, nrof_foreach_occ, length_idCexpressions(a_idCexpressions), True); } withexpressions t_pf_gen_foreachwith_vars( idCexpressions $a_idCexpressions, int occ, int nr, boolean listvars ) { ConsidCexpressions( ice = IdCexpression( id, ce ), t ): { char tmp[BUFSIZ]; withexpression w; withexpressions ws; ID w_id; if (listvars) { sprintf(tmp, "kc_fe_withlistvar_%d_%d", occ, nr); } else { sprintf(tmp, "kc_fe_withvar_%d_%d", occ, nr); } w_id = Id(Str(mkcasestring(tmp))); w = WEVariable(w_id); w->type = (listvars ? id : f_listelementphylum(id)); w->file = ce->file; w->line = ce->line; ice->id = w_id; ws = Conswithexpressions( w, t_pf_gen_foreachwith_vars( t, occ, nr-1, listvars)); ws->file = w->file; ws->line = w->line; return ws; } NilidCexpressions(): { return Nilwithexpressions(); } } /***************************************************************************/ ID subst_name( ID $n, casestring oldname, casestring newname ) { Id( Str( s )): { if (eq_casestring( s, oldname)) { ID tmp = Id(Str(newname)); tmp->file = n->file; tmp->line = n->line; return tmp; } else { return n; } } }