%{ /* * The Termprocessor Kimwitu * * Copyright (c) 1991 University of Twente, Dept TIOS. * All rights reserved. * */ %} %{ /* * kimwy.y */ #if ! (defined(lint) || defined(SABER) || defined(CODECENTER)) static char kimwy_yAccesSid[] = "@(#)$Id: kimwy.y,v 2.41 1998/01/29 18:04:21 belinfan Rel $"; #endif %} %{ #ifdef BISON_RECOVER /* Note that setting YYDEBUG is required even if you do not want to * set the yydebug variable because we use the symbol strings in * `yytname' for initialising costs and also for error messages. */ #define YYDEBUG 1 #define yyinsertcost(token) (token[0]=='\''?1:strlen(token)) #define yydeletecost(token) (token[0]=='\''?1:strlen(token)) #endif /* BISON_RECOVER */ %} %{ /***************************************************************************/ /* * Name conventions: tokens are in CAPITALS * nonterminals are in lowercase * operators are capitalized * */ %} %{ /* define our own macro if we have a 'standard' (ansi) C(++) compiler */ #ifndef KC_NO_STDC # if defined(__STDC__) || defined(__cplusplus) || defined(_WIN32) # define KC_STDC # endif #endif #ifdef KC_STDC # include /* for malloc and free */ #endif #include /* for strcat */ /* For windows (NT at least) we need to redifine alloca */ #if defined(_WIN32) && ! defined (__GNUC__) # define alloca _alloca # include #endif #include "k.h" #include "parse.h" #include "extocc.h" #include "defocc.h" #include "util.h" /* for the v_add_to routines */ #include "rk.h" /* for the rewrite_patternchains routine */ static ID pl_phylum; /* local kimwy.y var */ static withexpressions pl_withvariables; /* local kimwy.y var */ static withexpressionsstack pl_withvariablesstack; /* local kimwy.y var */ static idCexpressionsstack pl_idCexpressionsstack; /* local kimwy.y var */ static filelinestack pl_filelinestack; /* local kimwy.y var */ static nooperatorsstack pl_nooperatorsstack; /* local kimwy.y var */ static int non_default_outmostpattern = 0; /* local kimwy.y var */ #define dollar_mark_set() (!eq_withexpressions(pl_withvariables, Nilwithexpressions())) #define do_MainC() do { if ( dollar_mark_set() ) do_NORMAL(); else do_C(); } while(kc_zero_constant) extern void do_NORMAL(); extern void do_CEXPR(); extern void do_CEXPRDQ(); extern void do_CEXPRSQ(); extern void do_C(); extern void yyerror KC__P((char*)); extern int yylex(); #define pf_setfileline(x) do { (x)->file = pg_filename; \ (x)->line = pg_lineno; \ } while(kc_zero_constant) #define pf_pushfileline() pl_filelinestack = Consfilelinestack( FileLine( pg_filename, pg_lineno ), pl_filelinestack ) #define pf_setstacktopfileline(x) do { (x)->file = pl_filelinestack->u.Consfilelinestack.fileline_1->u.FileLine.casestring_1; \ (x)->line = pl_filelinestack->u.Consfilelinestack.fileline_1->u.FileLine.int_1; \ } while(kc_zero_constant) #define pf_topfileline() (pl_filelinestack->u.Consfilelinestack.fileline_1) #define pf_popfileline() do { filelinestack tmp_pl_filelinestack = pl_filelinestack; \ pl_filelinestack = pl_filelinestack->u.Consfilelinestack.filelinestack_1; \ free_fileline( tmp_pl_filelinestack->u.Consfilelinestack.fileline_1, True ); \ free_filelinestack( tmp_pl_filelinestack, False ); \ } while(kc_zero_constant) #define pf_setwithvariable(x) pl_withvariables = Conswithexpressions(WEVariable(x), pl_withvariables) #define pf_resetwithvariable() pl_withvariables = Nilwithexpressions() #define pf_push_no_operators() pl_nooperatorsstack = Consnooperatorsstack( non_default_outmostpattern, pl_nooperatorsstack ); #define pf_pop_no_operators() do { nooperatorsstack tmp_pl_nooperatorsstack = pl_nooperatorsstack; \ non_default_outmostpattern = pl_nooperatorsstack->u.Consnooperatorsstack.int_1; \ pl_nooperatorsstack = pl_nooperatorsstack->u.Consnooperatorsstack.nooperatorsstack_1; \ free_nooperatorsstack( tmp_pl_nooperatorsstack, False ); \ } while(kc_zero_constant) #define pf_pushwithvariable() pl_withvariablesstack = Conswithexpressionsstack( pl_withvariables, pl_withvariablesstack ) #define pf_topwithvariable() (pl_withvariablesstack->u.Conswithexpressionsstack.withexpressions_1) #define pf_popwithvariable() do { withexpressionsstack tmp_pl_withvariablesstack = pl_withvariablesstack; \ pl_withvariablesstack = pl_withvariablesstack->u.Conswithexpressionsstack.withexpressionsstack_1; \ free_withexpressionsstack( tmp_pl_withvariablesstack, False ); \ } while(kc_zero_constant) #define pf_pushidCexpressions(x) pl_idCexpressionsstack = ConsidCexpressionsstack( x, pl_idCexpressionsstack ) #define pf_topidCexpressions() (pl_idCexpressionsstack->u.ConsidCexpressionsstack.idCexpressions_1) #define pf_popidCexpressions() do { idCexpressionsstack tmp_pl_idCexpressionsstack = pl_idCexpressionsstack; \ pl_idCexpressionsstack = pl_idCexpressionsstack->u.ConsidCexpressionsstack.idCexpressionsstack_1; \ free_idCexpressionsstack( tmp_pl_idCexpressionsstack, False ); \ } while(kc_zero_constant) %} %token T_ID %token T_INT %token T_CNEWLINES %token T_CLINE %token T_CEXPRESSION %token T_DOLLARVAR %token T_INCLUDE %token T_INCLUDESTART %token T_INCLUDEEND %token T_LIST %token T_ARROW %token T_STATIC %token T_WITH %token T_FOREACH %token T_FOREACH_AFTER %token T_DEFAULT %token T_UNPBLOCKSTART %token T_UNPBLOCKEND %token T_PERCENTRVIEW %token T_PERCENTUVIEW %token T_PERCENTSTORAGECLASS %token T_AUTO %token T_REGISTER %token T_EXTERN %token T_TYPEDEF %token T_CONST %token T_VOLATILE %token T_DOTDOTDOT %type dollarvar %type id %type int /* %type string */ /* no %type for specification */ /* no %type for declarations */ /* no %type for declaration */ %type phylumdeclaration %type storageoption %type productionblock %type alternatives %type alternative %type arguments %type Ccode_option %type attributes_option %type attribute %type attribute_init_option %type idCexpressions %type idCexpression %type withCexpressions %type withCexpression %type Cexpression %type Cexpression_inner %type Cexpression_elem %type Cexpression_elem_inner %type CexpressionDQ %type CexpressionDQ_elem %type CexpressionSQ %type CexpressionSQ_elem %type MainCbody %type MainCbodyinC %type MainCBodycontinuation %type Cbody %type Ctext %type Ctext_elem %type foreach_continuation %type init_option %type foreach_end_continuation %type includedeclaration %type includefiles_option %type includefiles %type includes %type include %type rwdeclaration %type rwclauses_or_term %type rwclauses %type rwclause %type patternchains %type patternchain %type patternchainitem %type patternchainitem_lineinfo %type outmostpatterns %type outmostpattern %type pattern %type patternsoption %type patterns %type term %type termsoption %type terms %type withcases %type withcase %type unparsedeclaration %type unparseclauses %type unparseclause %type defuviewnames %type defrviewnames %type useviewnames %type unparseitems %type unparseitem %type unpsubterm %type unpattributes %type unpattribute %type viewnameoption %type uviewdeclaration %type rviewdeclaration %type storageclassdeclaration %type defstorageclasses %type ac_function_definition %type ac_declaration %type ac_declaration_list_option %type ac_declaration_list %type ac_declaration_specifiers %type ac_storage_class_specifier %type ac_type_specifier %type ac_type_qualifier %type ac_init_declarator_list_option %type ac_init_declarator_list %type ac_init_declarator %type ac_declarator %type ac_pointer_declarator %type ac_direct_declarator %type ac_fn_declarator %type ac_direct_fn_declarator %type ac_pointer %type ac_type_qualifier_list %type ac_parameter_type_list %type ac_parameter_list %type ac_parameter_declaration %type ac_identifier_list %type ac_abstract_declarator %type ac_direct_abstract_declarator %type ac_constant_expression_option %type ac_constant_expression %type ac_identifier %type ac_compound_statement %start specification %% dollarvar : T_DOLLARVAR { $$ = Int( $1 ); pf_setfileline( $$ ); } ; id : T_ID { $$ = Id( Str( $1 )); pf_setfileline( $$ ); } ; int : T_INT { $$ = Int( $1 ); pf_setfileline( $$ ); } ; /* string : STRING { $$ = String( $1 ); pf_setfileline( $$ ); } ; */ specification : { /* initialize variables and scanner state */ pl_filelinestack = Nilfilelinestack(); pl_nooperatorsstack = Nilnooperatorsstack(); pl_phylum = 0; pl_withvariables = Nilwithexpressions(); pl_withvariablesstack = Nilwithexpressionsstack(); pl_idCexpressionsstack = NilidCexpressionsstack(); do_NORMAL(); } declarations ; declarations : declaration | declarations declaration ; declaration : phylumdeclaration { Thephylumdeclarations = mergephylumdeclarations( $1, Thephylumdeclarations ); } | rwdeclaration { Therwdeclarations = Consrwdeclarations( $1, Therwdeclarations ); } /* | functiondeclaration { Thefndeclarations = Consfndeclarations( $1, Thefndeclarations ); } */ | ac_function_definition { Thefndeclarations = Consfndeclarations( $1, Thefndeclarations ); } | includedeclaration { } | unparsedeclaration { Theunparsedeclarations = Consunparsedeclarations( $1, Theunparsedeclarations ); } | uviewdeclaration { } | rviewdeclaration { } | storageclassdeclaration { } ; phylumdeclaration : id storageoption ':' { pl_phylum = $1; } productionblock Ccode_option ';' { $$ = PhylumDeclaration( $1, $2, $5, $6 ); v_extendoccur( pl_phylum, ITUserPhylum( $$ ) ); } ; storageoption : /* empty */ { $$ = NoStorageOption(); } | '{' id '}' { $$ = PositiveStorageOption( $2 ); v_extendoccur( $2, ITStorageClass() ); } | '{' '!' id '}' { $$ = NegativeStorageOption( $3 ); v_extendoccur( $3, ITStorageClass() ); } ; productionblock : /* empty */ { $$ = Emptyproductionblock(); } | T_LIST id { $$ = ListAlternatives( makeListAlternatives( pl_phylum, $2 ), $2 ); Theargsnumbers = insert_in_argsnumbers(0, Theargsnumbers); Theargsnumbers = insert_in_argsnumbers(2, Theargsnumbers); } | alternatives { $$ = NonlistAlternatives( $1 ); } ; alternatives : alternative { $$ = Consalternatives( $1, Nilalternatives() ); } | alternatives '|' alternative { $$ = Consalternatives( $3, $1 ); } ; alternative : id '(' { pg_no_of_arguments = 0; } arguments { Theargsnumbers = insert_in_argsnumbers(pg_no_of_arguments, Theargsnumbers); } ')' { $$ = Alternative( $1, $4 ); v_extendoccur( $1, ITUserOperator( $$, pl_phylum ) ); } ; arguments : /* empty */ { $$ = Nilarguments(); } | arguments id { $$ = Consarguments( $2, $1 ); pg_no_of_arguments++; } ; Ccode_option : /* empty */ { $$ = CcodeOption( Nilattributes(), NilCtexts() ); } | '{' attributes_option init_option '}' { $$ = CcodeOption( $2, $3 ); } ; attributes_option : /* empty */ { $$ = Nilattributes(); } | attributes_option attribute { $$ = Consattributes( $2, $1 ); } ; attribute : id id attribute_init_option ';' { $$ = Attribute( $1, $2, $3 ); } ; attribute_init_option : /* empty */ { $$ = Noattribute_initialisation(); } | '=' { do_CEXPR(); } Cexpression { do_NORMAL(); $$ = Yesattribute_initialisation( $3 ); } ; /* * we use the fact that the empty list is the first 'element' that is * parsed into the list */ Cexpression : /* empty */ { $$ = NilCexpression(); pf_setfileline( $$ ); } | Cexpression Cexpression_elem { $$ = ConsCexpression( $2, $1 ); $$->file = $1->file; $$->line = $1->line; } ; Cexpression_elem : T_CEXPRESSION { $$ = CExpressionPart( $1 ); } | dollarvar { $$ = CExpressionDollarvar( $1 ); } | '\n' { $$ = CExpressionNl( 1 ); } | T_CNEWLINES { $$ = CExpressionNl( $1 ); } | '\"' CexpressionDQ '\"' { $$ = CExpressionDQ( $2 ); } | '\'' CexpressionSQ '\'' { $$ = CExpressionSQ( $2 ); } | '(' Cexpression_inner ')' { $$ = CExpressionPack( $2 ); } | '[' Cexpression_inner ']' { $$ = CExpressionArray( $2 ); } ; Cexpression_inner : /* empty */ { $$ = NilCexpression(); pf_setfileline( $$ ); } | Cexpression_inner Cexpression_elem_inner { $$ = ConsCexpression( $2, $1 ); $$->file = $1->file; $$->line = $1->line; } ; Cexpression_elem_inner : Cexpression_elem { $$ = $1; } | ',' { $$ = CExpressionPart( mkcasestring(",") ); } ; CexpressionDQ : /* empty */ { $$ = NilCexpressionDQ(); } | CexpressionDQ CexpressionDQ_elem { $$ = ConsCexpressionDQ( $2, $1 ); } ; CexpressionDQ_elem : T_CEXPRESSION { $$ = CExpressionDQPart( $1 ); } | '\n' { $$ = CExpressionDQNl( 1 ); } ; CexpressionSQ : /* empty */ { $$ = NilCexpressionSQ(); } | CexpressionSQ CexpressionSQ_elem { $$ = ConsCexpressionSQ( $2, $1 ); } ; CexpressionSQ_elem : T_CEXPRESSION { $$ = CExpressionSQPart( $1 ); } | '\n' { $$ = CExpressionSQNl( 1 ); } ; idCexpressions : idCexpression { $$ = ConsidCexpressions( $1, NilidCexpressions() ); } | idCexpressions ',' idCexpression { $$ = ConsidCexpressions( $3, $1 ); } ; idCexpression : id { do_CEXPR(); } Cexpression { do_NORMAL(); } { $$ = IdCexpression( $1, $3 ); } ; withCexpression : Cexpression { $$ = WECexpression( $1 ); pf_setstacktopfileline( $$ ); } ; withCexpressions : withCexpression { $$ = Conswithexpressions( $1, Nilwithexpressions() ); } | withCexpressions ',' { pf_pushfileline(); } withCexpression { $$ = Conswithexpressions( $4, $1 ); pf_popfileline(); } ; /* * use global variable to pass/save the $fnargument that can be picked up * and inserted in the withcases in the MainCbody continuation so that * it can return a complete CtextWithexpression */ MainCbody : '{' { do_MainC(); pf_pushfileline(); pf_pushwithvariable(); pf_resetwithvariable(); } MainCBodycontinuation { do_NORMAL(); } '}' { $$ = $3; pf_setstacktopfileline( $$ ); pf_popfileline(); pf_popwithvariable(); } ; MainCbodyinC : '{' { do_MainC(); pf_pushfileline(); pf_pushwithvariable(); pf_resetwithvariable(); } MainCBodycontinuation { do_C(); } '}' { $$ = $3; pf_setstacktopfileline( $$ ); pf_popfileline(); pf_popwithvariable(); } ; MainCBodycontinuation : Ctext { $$ = $1; pf_setstacktopfileline( $$ ); } | withcases { Ctext_elem tmp = CTextWithexpression( pf_topwithvariable(), $1, NotInForeachContext() ); pf_setstacktopfileline( tmp ); $$ = ConsCtext( tmp, NilCtext() ); pf_setstacktopfileline( $$ ); if (! non_default_outmostpattern ) v_report(NonFatal( NoFileLine(), Problem1S( "can not infer type from `default' pattern(s)" ))); non_default_outmostpattern = 0; } ; Cbody : '{' { do_C(); pf_pushfileline(); pf_push_no_operators(); } Ctext { do_NORMAL(); } '}' { $$ = $3; pf_setstacktopfileline( $$ ); pf_popfileline(); pf_pop_no_operators(); } ; Ctext : /* empty */ { $$ = NilCtext(); pf_setfileline( $$ ); } | Ctext { pf_pushfileline(); } Ctext_elem { $$ = ConsCtext( $3, $1 ); pf_setstacktopfileline( $3 ); pf_popfileline(); $$->file = $1->file; $$->line = $1->line; } ; Ctext_elem : T_CLINE { $$ = CTextLine( $1 ); } | dollarvar { $$ = CTextDollarVar( $1 ); } | '\n' { $$ = CTextNl( 1 ); } | T_CNEWLINES { $$ = CTextNl( $1 ); } | '\"' { do_CEXPRDQ(); } CexpressionDQ '\"' { do_C(); $$ = CTextCexpressionDQ( $3 ); } | '\'' { do_CEXPRSQ(); } CexpressionSQ '\'' { do_C(); $$ = CTextCexpressionSQ( $3 ); } /* | '(' Cexpression ')' */ | Cbody { do_C(); $$ = CTextCbody( $1 ); } | T_FOREACH { do_NORMAL(); } foreach_continuation { do_C(); $$ = $3; } | T_WITH { do_NORMAL(); } '(' { do_CEXPR(); pf_pushfileline(); } withCexpressions { do_NORMAL(); pf_popfileline(); } ')' '{' withcases '}' { do_C(); $$ = CTextWithexpression( $5, $9, NotInForeachContext() ); if (! non_default_outmostpattern ) v_report(NonFatal( NoFileLine(), Problem1S( "can not infer type from `default' pattern(s)" ))); non_default_outmostpattern = 0; } ; foreach_continuation : '(' patternchain ';' { non_default_outmostpattern = 0; } idCexpressions ')' MainCbodyinC /* or something similar */ { pf_pushidCexpressions($5); } foreach_end_continuation { patternchains pc_list = Conspatternchains($2, Nilpatternchains()); patternchains rewritten = rewrite_patternchains(pc_list, base_rview); withexpressions wexpr = pf_gen_foreachwith_vars( $5 ); Ctext_elem ctwe = CTextWithexpression( wexpr, Conswithcases( Withcase( syn_patternchains_fileline( rewritten, pg_filename, pg_lineno ), $7 ), Nilwithcases() ), InForeachContext($2) ); Ctext ctxts0 = NilCtext(); Ctext ctxts1 = ConsCtext( ctwe, ctxts0 ); pf_setstacktopfileline( ctwe ); pf_setstacktopfileline( ctxts0 ); pf_setstacktopfileline( ctxts1 ); check_no_patternchaingroup_in_patternchain( $2->file, $2->line, $2, "'foreach variable/pattern'" ); $$ = CTextForeachexpression( $2, $5, wexpr, ctxts1, $9); pf_popidCexpressions(); } ; foreach_end_continuation : /* empty */ { $$ = NoForeachAfter(); } | T_FOREACH_AFTER { do_NORMAL(); pf_pushfileline(); } '(' patternchain { non_default_outmostpattern = 0; } ')' MainCbodyinC { patternchains pc_list = Conspatternchains($4, Nilpatternchains()); patternchains rewritten = rewrite_patternchains(pc_list, base_rview); withexpressions wexpr = pf_gen_foreachwith_listvars( pf_topidCexpressions() ); Ctext_elem ctwe = CTextWithexpression( wexpr, Conswithcases( Withcase( syn_patternchains_fileline( rewritten, pg_filename, pg_lineno ), $7 ), Nilwithcases() ), InForeachContext($4) ); Ctext ctxts0 = NilCtext(); Ctext ctxts1 = ConsCtext( ctwe, ctxts0 ); pf_setstacktopfileline( ctwe ); pf_setstacktopfileline( ctxts0 ); pf_setstacktopfileline( ctxts1 ); check_no_patternchaingroup_or_pattern_in_patternchain( $4->file, $4->line, $4, "'foreach variable/pattern'" ); $$ = ForeachAfter( $4, pf_topidCexpressions(), wexpr, ctxts1 ); pf_setstacktopfileline( $$ ); pf_popfileline(); } ; init_option : /* empty */ { $$ = NilCtexts(); } | Cbody { $$ = ConsCtexts( $1, NilCtexts() ); } ; includedeclaration : T_INCLUDESTART includefiles_option { pf_pushfileline(); } includes T_INCLUDEEND {{includedeclaration pl_includedeclaration = IncludeDeclaration( $4 ); set_includefiles( $2, pl_includedeclaration ); pf_setstacktopfileline( pl_includedeclaration ); pf_popfileline(); }} ; includefiles_option : /* empty */ {{ includefile pl_includefile = IncludeFile( mkcasestring(INC_CODE) ); $$ = Consincludefiles( pl_includefile, Nilincludefiles() ); }} | includefiles { $$ = $1; } ; includefiles : T_ID {{ includefile pl_includefile = IncludeFile( $1 ); if (pl_includefile->newinclude) { v_report(Warning( NoFileLine(), ProblemSC( "old include redirection keyword (please replace the `KIMW_' part by `KC_'):", $1 ))); pl_includefile = pl_includefile->newinclude; } if ((pl_includefile->inc_type == include_file) || (pl_includefile->inc_type == include_header)) { $$ = Consincludefiles( pl_includefile, Nilincludefiles() ); } else { v_report(NonFatal( NoFileLine(), ProblemSC( "unknown include redirection keyword:", $1 ))); $$ = Nilincludefiles(); } }} | includefiles T_ID {{ includefile pl_includefile = IncludeFile( $2 ); if (pl_includefile->newinclude) { v_report(Warning( NoFileLine(), ProblemSC( "old include redirection keyword (please replace the `KIMW_' part by `KC_'):", $2 ))); pl_includefile = pl_includefile->newinclude; } if ((pl_includefile->inc_type == include_file) || (pl_includefile->inc_type == include_header)) { $$ = Consincludefiles( pl_includefile, $1 ); } else { v_report(NonFatal( NoFileLine(), ProblemSC( "unknown include redirection keyword:", $2 ))); $$ = $1; } }} ; includes : /* empty */ { $$ = Nilincludes(); } | includes include { $$ = Consincludes( $2, $1 ); } ; include : T_INCLUDE { $$ = Include( $1 ); } | '\n' { $$ = IncludeNl( 1 ); } ; rwdeclaration : outmostpatterns T_ARROW { if (! non_default_outmostpattern ) v_report(NonFatal( NoFileLine(), Problem1S( "can not infer type from `default' pattern(s)" ))); non_default_outmostpattern = 0; } rwclauses_or_term ';' { $$ = RwDeclaration( $1, $4 ); } ; rwclauses_or_term : term /* to be depricated */ { $$ = Consrewriteclauses( RewriteClause( Consviewnames( Id( Str( mkcasestring( "base_rview" ))), Nilviewnames() ), $1 ), Nilrewriteclauses() ); } | rwclauses { $$ = $1; } ; rwclauses : rwclause { $$ = Consrewriteclauses( $1, Nilrewriteclauses() ); } | rwclauses rwclause { $$ = Consrewriteclauses( $2, $1 ); } ; rwclause : '<' useviewnames ':' term '>' /* if no view was defined, we replace the implicit base_rview * (Nilviewnames) by an explicit one (ie. base_rview) */ { if (eq_viewnames( $2, Nilviewnames())) { $$ = RewriteClause( Consviewnames( Id( Str( mkcasestring( "base_rview" ))), $2 ), $4 ); } else { $$ = RewriteClause( $2, $4 ); } } ; patternchains : patternchain { $$ = Conspatternchains( $1, Nilpatternchains() ); } | patternchains ',' patternchain { $$ = Conspatternchains( $3, $1 ); } ; patternchain : patternchainitem_lineinfo { $$ = Conspatternchain( $1, Nilpatternchain() ); } | patternchain '&' patternchainitem_lineinfo { $$ = Conspatternchain( $3, $1 ); } ; patternchainitem_lineinfo : { pf_pushfileline(); } patternchainitem { $$ = $2; pf_setstacktopfileline($$); pf_popfileline(); } ; patternchainitem : outmostpattern { $$ = PatternchainitemOutmost( $1 ); } | '(' patternchains ')' { $$ = PatternchainitemGroup( $2 ); } | '$' id /* this rule is to be used only in foreach statements */ { $$ = PatternchainitemDollarid( $2 ); pf_setwithvariable( $2 ); } ; outmostpatterns : outmostpattern { $$ = Consoutmostpatterns( $1, Niloutmostpatterns() ); } | outmostpatterns ',' outmostpattern { $$ = Consoutmostpatterns( $3, $1 ); } ; outmostpattern : id /* operator (wildcard for subterms) */ { $$ = OPOperatorWildcard( $1 ); non_default_outmostpattern = 1; } | id '(' patternsoption ')' /* operator + subterms */ { $$ = OPOperator( $1, $3 ); non_default_outmostpattern = 1; } | id '=' outmostpattern /* non-leaf variable */ { $$ = OPNonLeafVariable( $1, $3 ); non_default_outmostpattern = 1; } | '*' /* wildcard */ { $$ = OPWildcard(); } | T_DEFAULT /* wildcard */ { $$ = OPDefault(); } ; pattern : id /* variable */ { $$ = PVariable( $1 ); } | id '(' patternsoption ')' /* operator + subterms */ { $$ = POperator( $1, $3 ); } | '*' /* wildcard */ { $$ = PWildcard(); } | T_DEFAULT /* wildcard */ { $$ = PWildcard(); } | id '=' pattern /* non-leaf variable */ { $$ = PNonLeafVariable( $1, $3 ); } | '\"' { do_CEXPRDQ(); } CexpressionDQ '\"' /* string literal */ { do_NORMAL(); $$ = PStringLiteral( $3 ); } | int /* int literal */ { $$ = PIntLiteral( $1 ); } ; patternsoption : /* empty */ { $$ = Nilpatterns(); } | patterns { $$ = $1; } ; patterns : pattern { $$ = Conspatterns( $1, Nilpatterns() ); } | patterns ',' pattern { $$ = Conspatterns( $3, $1 ); } ; term: id /* variable */ { $$ = TVariable( $1 ); } | id '(' termsoption ')' /* operator + subterms */ { $$ = TOperator( $1, $3 ); } | '\"' { do_CEXPRDQ(); } CexpressionDQ '\"' /* string literal */ { do_NORMAL(); $$ = TStringLiteral( $3 ); } | int /* int literal */ { $$ = TIntLiteral( $1 ); } ; termsoption : /* empty */ { $$ = Nilterms(); } | terms { $$ = $1; } ; terms : term { $$ = Consterms( $1, Nilterms() ); } | terms ',' term { $$ = Consterms( $3, $1 ); } ; withcases : withcase { $$ = Conswithcases( $1, Nilwithcases() ); } | withcases withcase { $$ = Conswithcases( $2, $1 ); } ; withcase : patternchains ':' Cbody { $$ = Withcase( syn_patternchains_fileline(rewrite_patternchains($1, base_rview), pg_filename, pg_lineno ), $3 ); } ; unparsedeclaration : outmostpatterns T_ARROW { if (! non_default_outmostpattern ) v_report(NonFatal( NoFileLine(), Problem1S( "can not infer type from `default' pattern(s)" ))); non_default_outmostpattern = 0; } unparseclauses ';' { $$ = UnparseDeclaration( $1, $4 ); } ; unparseclauses : unparseclause { $$ = Consunparseclauses( $1, Nilunparseclauses() ); } | unparseclauses unparseclause { $$ = Consunparseclauses( $2, $1 ); } ; unparseclause : '[' useviewnames ':' unparseitems ']' /* if no view was defined, we replace the implicit base_uview * (Nilviewnames) by an explicit one (ie. base_uview) */ { if (eq_viewnames( $2, Nilviewnames())) { $$ = UnparseClause( Consviewnames( Id( Str( mkcasestring( "base_uview" ))), $2 ), $4 ); } else { $$ = UnparseClause( $2, $4 ); } } ; useviewnames : /* empty */ { $$ = Nilviewnames(); } | useviewnames id { $$ = Consviewnames( subst_name( $2, mkcasestring( "base_view" ), mkcasestring( "base_uview" )), $1 ); } unparseitems : /*empty*/ { $$ = Nilunparseitems(); } | unparseitems unparseitem { $$ = Consunparseitems( $2, $1 ); } ; unparseitem : '\"' { do_CEXPRDQ(); } CexpressionDQ '\"' /* string literal */ { do_NORMAL(); } viewnameoption { $$ = UnpStr( $3, $6 ); } | unpsubterm viewnameoption { $$ = UnpSubexpr( $1, $2 ); } | Cbody { $$ = UnpCtext( $1 ); } | T_UNPBLOCKSTART unparseitems T_UNPBLOCKEND { $$ = UnpBody( $2 ); } ; unpsubterm : id { $$ = UnpSubTerm( $1 ); } | dollarvar { $$ = UnpDollarvarTerm( $1 ); } | id unpattributes { $$ = UnpSubAttr( $1, $2 ); } | dollarvar unpattributes { $$ = UnpDollarvarAttr( $1, $2 ); } | '(' id ')' id { $$ = UnpCastedVariable( $2, $4 ); } ; unpattributes : unpattribute { $$ = Consunpattributes( $1, Nilunpattributes() ); } | unpattributes unpattribute { $$ = Consunpattributes( $2, $1 ); } ; unpattribute : T_ARROW id { $$ = $2; } ; viewnameoption : /*empty*/ { $$ = NoViewname(); } | ':' id { $$ = YesViewname( $2 ); } ; uviewdeclaration : T_PERCENTUVIEW defuviewnames ';' { $$ = $2; pg_uviewshavebeendefined = True; } ; defuviewnames : id { $$ = Consviewnames( $1, Nilviewnames()); v_add_to_uviewnames( $1 ); v_extendoccur( $1, ITUserUView() ); } | defuviewnames id { $$ = Consviewnames( $2, $1 ); v_add_to_uviewnames( $2 ); v_extendoccur( $2, ITUserUView() ); } | defuviewnames ',' id { $$ = Consviewnames( $3, $1 ); v_add_to_uviewnames( $3 ); v_extendoccur( $3, ITUserUView() ); } ; rviewdeclaration : T_PERCENTRVIEW defrviewnames ';' { $$ = $2; pg_rviewshavebeendefined = True; } ; defrviewnames : id { $$ = Consviewnames( $1, Nilviewnames()); v_add_to_rviewnames( $1 ); v_extendoccur( $1, ITUserRView() ); } | defrviewnames id { $$ = Consviewnames( $2, $1 ); v_add_to_rviewnames( $2 ); v_extendoccur( $2, ITUserRView() ); } | defrviewnames ',' id { $$ = Consviewnames( $3, $1 ); v_add_to_rviewnames( $3 ); v_extendoccur( $3, ITUserRView() ); } ; storageclassdeclaration : T_PERCENTSTORAGECLASS defstorageclasses ';' { $$ = $2; pg_storageclasseshavebeendefined = True; } ; defstorageclasses : id { $$ = Consstorageclasses( $1, Nilstorageclasses()); v_add_to_storageclasses( $1, f_emptyId() ); v_extendoccur( $1, ITStorageClass() ); } | defstorageclasses id { $$ = Consstorageclasses( $2, $1 ); v_add_to_storageclasses( $2, f_emptyId() ); v_extendoccur( $2, ITStorageClass() ); } | defstorageclasses ',' id { $$ = Consstorageclasses( $3, $1 ); v_add_to_storageclasses( $3, f_emptyId() ); v_extendoccur( $3, ITStorageClass() ); } ; ac_function_definition : ac_declaration_specifiers ac_fn_declarator ac_declaration_list_option ac_compound_statement { ID tmp_id = f_ID_of_declarator($2); fnclass tmp_type = f_fnclass_info($1, pg_filename); /* first check before making the FnAcDeclaration, to keep the * error message in a nice order */ check_proto_ac_parameter_declaration( tmp_id->file, tmp_id->line, $3, $2 ); $$ = FnAcDeclaration( $1, $2, $3, $4, tmp_id, tmp_type ); pf_resetwithvariable(); v_defoccur( tmp_id, ITUserFunction( tmp_type ) ); $$->file = pg_filename; $$->last_line = pg_lineno; } ; ac_declaration : ac_declaration_specifiers ac_init_declarator_list_option ';' { $$ = AcDeclaration( $1, $2 ); } ; ac_declaration_list_option : /* empty */ { $$ = Nilac_declaration_list(); } | ac_declaration_list { $$ = $1; } ; ac_declaration_list : ac_declaration { $$ = Consac_declaration_list( $1, Nilac_declaration_list() ); } | ac_declaration_list ac_declaration { $$ = Consac_declaration_list( $2, $1 ); } ; /* simplified: we now _need_ exactely one type, * no more (eg. 'long long' not supported), * no less (implicit 'int' not supported) */ ac_declaration_specifiers : ac_type_specifier { $$ = Consac_declaration_specifiers( AcDeclSpecTypeSpec( $1 ), Nilac_declaration_specifiers() ); } | ac_storage_class_specifier ac_type_specifier { $$ = Consac_declaration_specifiers( AcDeclSpecTypeSpec( $2 ), Consac_declaration_specifiers( AcDeclSpecStorageSpec( $1 ), Nilac_declaration_specifiers() )); } | ac_type_qualifier ac_type_specifier { $$ = Consac_declaration_specifiers( AcDeclSpecTypeSpec( $2 ), Consac_declaration_specifiers( AcDeclSpecTypeQual( $1 ), Nilac_declaration_specifiers() )); } | ac_storage_class_specifier ac_type_qualifier ac_type_specifier { $$ = Consac_declaration_specifiers( AcDeclSpecTypeSpec( $3 ), Consac_declaration_specifiers( AcDeclSpecTypeQual( $2 ), Consac_declaration_specifiers( AcDeclSpecStorageSpec( $1 ), Nilac_declaration_specifiers() ))); } ; ac_storage_class_specifier : T_AUTO { $$ = AcAuto(); } | T_REGISTER { $$ = AcRegister(); } | T_STATIC { $$ = AcStatic(); } | T_EXTERN { $$ = AcExtern(); } | T_TYPEDEF { $$ = AcTypedef(); } ; ac_type_specifier : id /* to simplify */ { $$ = AcTypeSpec( $1 ); } ; ac_type_qualifier : T_CONST { $$ = AcConst(); } | T_VOLATILE { $$ = AcVolatile(); } ; ac_init_declarator_list_option : /* empty */ { $$ = Nilac_init_declarator_list(); } | ac_init_declarator_list { $$ = $1; } ; ac_init_declarator_list : ac_init_declarator { $$ = Consac_init_declarator_list( $1, Nilac_init_declarator_list() ); } | ac_init_declarator_list ',' ac_init_declarator { $$ = Consac_init_declarator_list( $3, $1 ); } ; ac_init_declarator : ac_declarator { $$ = AcInitDecl( $1 ); } /* this one commented out for simplification | ac_declarator '=' ac_initializer */ ; ac_fn_declarator : ac_direct_fn_declarator { $$ = AcDeclarator( Nopointer(), $1 ); } | ac_pointer ac_direct_fn_declarator { $$ = AcDeclarator( Yespointer( $1 ), $2 ); } ; ac_declarator : ac_direct_declarator { $$ = AcDeclarator(Nopointer(), $1 ); } | ac_pointer ac_direct_declarator { $$ = AcDeclarator( Yespointer( $1 ), $2 ); } ; ac_pointer_declarator : ac_pointer ac_direct_declarator { $$ = AcDeclarator( Yespointer( $1 ), $2 ); } ; ac_direct_declarator : ac_identifier { $$ = AcDirectDeclId( $1 ); } | '(' ac_pointer_declarator ')' { $$ = AcDirectDeclPack( $2 ); } | ac_direct_declarator '[' ac_constant_expression_option ']' { $$ = AcDirectDeclArray( $1, $3 ); } | ac_direct_declarator '(' ac_parameter_type_list ')' { $$ = AcDirectDeclProto( $1, $3 ); } | ac_direct_declarator '(' ')' { $$ = AcDirectDeclKandR( $1, Nilac_identifier_list() ); } | ac_direct_declarator '(' ac_identifier_list ')' { $$ = AcDirectDeclKandR( $1, $3 ); } ; ac_direct_fn_declarator : ac_identifier '(' ac_parameter_type_list ')' { $$ = AcDirectDeclProto( AcDirectDeclId( $1 ), $3 ); } | ac_identifier '(' ')' { $$ = AcDirectDeclKandR( AcDirectDeclId( $1 ), Nilac_identifier_list() ); } | ac_identifier '(' ac_identifier_list ')' { $$ = AcDirectDeclKandR( AcDirectDeclId( $1 ), $3 ); } ; ac_pointer : '*' { $$ = AcPointerNil( Nilac_type_qualifier_list() ); } | '*' ac_type_qualifier_list { $$ = AcPointerNil( $2 ); } | '*' ac_pointer { $$ = AcPointerCons( Nilac_type_qualifier_list(), $2 ); } | '*' ac_type_qualifier_list ac_pointer { $$ = AcPointerCons( $2, $3 ); } ; ac_type_qualifier_list : ac_type_qualifier { $$ = Consac_type_qualifier_list( $1, Nilac_type_qualifier_list() ); } | ac_type_qualifier_list ac_type_qualifier { $$ = Consac_type_qualifier_list( $2, $1 ); } ; ac_parameter_type_list : ac_parameter_list { $$ = AcParList( $1 ); } | ac_parameter_list ',' T_DOTDOTDOT { $$ = AcParList3Dot( $1 ); } ; ac_parameter_list : ac_parameter_declaration { $$ = Consac_parameter_list( $1, Nilac_parameter_list() ); } | ac_parameter_list ',' ac_parameter_declaration { $$ = Consac_parameter_list( $3, $1 ); } ; ac_parameter_declaration : ac_declaration_specifiers ac_declarator { $$ = AcParDeclDecl( $1, $2 ); } | ac_declaration_specifiers ac_abstract_declarator { $$ = AcParDeclAbsdecl( $1, $2 ); } ; ac_identifier_list : ac_identifier { $$ = Consac_identifier_list( $1, Nilac_identifier_list() ); } | ac_identifier_list ',' ac_identifier { $$ = Consac_identifier_list( $3, $1 ); } ; ac_abstract_declarator : ac_pointer { $$ = AcAbsdeclPointer( $1 ); } | ac_direct_abstract_declarator { $$ = AcAbsdeclDirdecl( Nopointer(), $1 ); } | ac_pointer ac_direct_abstract_declarator { $$ = AcAbsdeclDirdecl( Yespointer( $1 ), $2 ); } ; ac_direct_abstract_declarator : '(' ac_abstract_declarator ')' { $$ = AcDirAbsdeclPack( $2 ); } | ac_direct_abstract_declarator '[' ac_constant_expression_option ']' { $$ = AcDirAbsdeclArray( Yesac_direct_abstract_declarator( $1 ), $3 ); } | '[' ac_constant_expression_option ']' { $$ = AcDirAbsdeclArray( Noac_direct_abstract_declarator(), $2 ); } | ac_direct_abstract_declarator '(' ')' { $$ = AcDirAbsdeclFn( Yesac_direct_abstract_declarator( $1 ), AcParList( Nilac_parameter_list() )); } | ac_direct_abstract_declarator '(' ac_parameter_type_list ')' { $$ = AcDirAbsdeclFn( Yesac_direct_abstract_declarator( $1 ), $3 ); } | '(' ')' { $$ = AcDirAbsdeclFn( Noac_direct_abstract_declarator(), AcParList( Nilac_parameter_list() )); } | '(' ac_parameter_type_list ')' { $$ = AcDirAbsdeclFn( Noac_direct_abstract_declarator(), $2 ); } ; /* trivial rule, because a Cexpression can be empty, * so we don't need an 'empty' rule here */ ac_constant_expression_option : ac_constant_expression { $$ = Yesac_constant_expression( $1 ); } ; ac_constant_expression : { do_CEXPR(); } Cexpression { do_NORMAL(); $$ = AcConstExpr( $2 ); } ; ac_identifier : id { $$ = $1; } | '$' id /* added $ var */ { $$ = $2; pf_setwithvariable( $2 ); } ; ac_compound_statement : MainCbody { $$ = $1; } ;