# Torturing Bison. -*- Autotest -*- # Copyright 2001 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. AT_BANNER([[Torture Tests.]]) # AT_DATA_STACK_TORTURE(C-PROLOGUE) # --------------------------------- # A parser specialized in torturing the stack size. m4_define([AT_DATA_STACK_TORTURE], [# A grammar of parens growing the stack thanks to right recursion. # exp: AT_DATA([input.y], [[%{ #include #include #include ]$1[ static int yylex (void); static void yyerror (const char *msg); #define YYPRINT(File, Type, Value) \ fprintf (File, " (%d, stack size = %d, max = %d)", \ Value, yyssp - yyss + 1, yystacksize); %} %error-verbose %debug %token WAIT_FOR_EOF %% exp: WAIT_FOR_EOF exp | ; %% static void yyerror (const char *msg) { fprintf (stderr, "%s\n", msg); exit (1); } /* There are YYLVAL_MAX of WAIT_FOR_EOFs. */ unsigned int yylval_max; static int yylex (void) { if (yylval--) return WAIT_FOR_EOF; else return EOF; } int main (int argc, const char **argv) { assert (argc == 2); yylval = atoi (argv[1]); yydebug = 1; return yyparse (); } ]]) AT_CHECK([bison input.y -o input.c]) AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore]) ]) ## -------------------------------------- ## ## Exploding the Stack Size with Alloca. ## ## -------------------------------------- ## AT_SETUP([Exploding the Stack Size with Alloca]) AT_DATA_STACK_TORTURE # Below the limit of 200. AT_CHECK([input 20], 0, [], [ignore]) # Two enlargements: 2 * 2 * 200. AT_CHECK([input 900], 0, [], [ignore]) # Fails: beyond the limit of 10,000 (which we don't reach anyway since we # multiply by two starting at 200 => 5120 is the last possible). AT_CHECK([input 10000], 1, [], [ignore]) AT_CLEANUP ## -------------------------------------- ## ## Exploding the Stack Size with Malloc. ## ## -------------------------------------- ## AT_SETUP([Exploding the Stack Size with Malloc]) AT_DATA_STACK_TORTURE([[#define YYSTACK_USE_ALLOCA 0]]) # Below the limit of 200. AT_CHECK([input 20], 0, [], [ignore]) # Two enlargements: 2 * 2 * 200. AT_CHECK([input 900], 0, [], [ignore]) # Fails: beyond the limit of 10,000 (which we don't reach anyway since we # multiply by two starting at 200 => 5120 is the possible). AT_CHECK([input 10000], 1, [], [ignore]) AT_CLEANUP ## ----------------- ## ## GNU AWK Grammar. ## ## ----------------- ## AT_SETUP([GNU AWK Grammar]) # We have been careful to strip all the actions excepts the # mid-rule actions. We rely on %expect to check that there are # indeed 65 SR conflicts. # # Bison was once wrong, due to an incorrect computation of nullable. # It reported 485 SR conflicts! AT_DATA([[input.y]], [[%expect 65 %token FUNC_CALL NAME REGEXP %token ERROR %token YNUMBER YSTRING %token RELOP APPEND_OP %token ASSIGNOP MATCHOP NEWLINE CONCAT_OP %token LEX_BEGIN LEX_END LEX_IF LEX_ELSE LEX_RETURN LEX_DELETE %token LEX_WHILE LEX_DO LEX_FOR LEX_BREAK LEX_CONTINUE %token LEX_PRINT LEX_PRINTF LEX_NEXT LEX_EXIT LEX_FUNCTION %token LEX_GETLINE LEX_NEXTFILE %token LEX_IN %token LEX_AND LEX_OR INCREMENT DECREMENT %token LEX_BUILTIN LEX_LENGTH /* Lowest to highest */ %right ASSIGNOP %right '?' ':' %left LEX_OR %left LEX_AND %left LEX_GETLINE %nonassoc LEX_IN %left FUNC_CALL LEX_BUILTIN LEX_LENGTH %nonassoc ',' %nonassoc MATCHOP %nonassoc RELOP '<' '>' '|' APPEND_OP TWOWAYIO %left CONCAT_OP %left YSTRING YNUMBER %left '+' '-' %left '*' '/' '%' %right '!' UNARY %right '^' %left INCREMENT DECREMENT %left '$' %left '(' ')' %% start : opt_nls program opt_nls ; program : rule | program rule | error | program error | /* empty */ ; rule : LEX_BEGIN {} action | LEX_END {} action | LEX_BEGIN statement_term | LEX_END statement_term | pattern action | action | pattern statement_term | function_prologue function_body ; func_name : NAME | FUNC_CALL | lex_builtin ; lex_builtin : LEX_BUILTIN | LEX_LENGTH ; function_prologue : LEX_FUNCTION {} func_name '(' opt_param_list r_paren opt_nls ; function_body : l_brace statements r_brace opt_semi opt_nls | l_brace r_brace opt_semi opt_nls ; pattern : exp | exp ',' exp ; regexp /* * In this rule, want_regexp tells yylex that the next thing * is a regexp so it should read up to the closing slash. */ : '/' {} REGEXP '/' ; action : l_brace statements r_brace opt_semi opt_nls | l_brace r_brace opt_semi opt_nls ; statements : statement | statements statement | error | statements error ; statement_term : nls | semi opt_nls ; statement : semi opt_nls | l_brace r_brace | l_brace statements r_brace | if_statement | LEX_WHILE '(' exp r_paren opt_nls statement | LEX_DO opt_nls statement LEX_WHILE '(' exp r_paren opt_nls | LEX_FOR '(' NAME LEX_IN NAME r_paren opt_nls statement | LEX_FOR '(' opt_exp semi opt_nls exp semi opt_nls opt_exp r_paren opt_nls statement | LEX_FOR '(' opt_exp semi opt_nls semi opt_nls opt_exp r_paren opt_nls statement | LEX_BREAK statement_term | LEX_CONTINUE statement_term | print '(' expression_list r_paren output_redir statement_term | print opt_rexpression_list output_redir statement_term | LEX_NEXT statement_term | LEX_NEXTFILE statement_term | LEX_EXIT opt_exp statement_term | LEX_RETURN {} opt_exp statement_term | LEX_DELETE NAME '[' expression_list ']' statement_term | LEX_DELETE NAME statement_term | exp statement_term ; print : LEX_PRINT | LEX_PRINTF ; if_statement : LEX_IF '(' exp r_paren opt_nls statement | LEX_IF '(' exp r_paren opt_nls statement LEX_ELSE opt_nls statement ; nls : NEWLINE | nls NEWLINE ; opt_nls : /* empty */ | nls ; input_redir : /* empty */ | '<' simp_exp ; output_redir : /* empty */ | '>' exp | APPEND_OP exp | '|' exp | TWOWAYIO exp ; opt_param_list : /* empty */ | param_list ; param_list : NAME | param_list comma NAME | error | param_list error | param_list comma error ; /* optional expression, as in for loop */ opt_exp : /* empty */ | exp ; opt_rexpression_list : /* empty */ | rexpression_list ; rexpression_list : rexp | rexpression_list comma rexp | error | rexpression_list error | rexpression_list error rexp | rexpression_list comma error ; opt_expression_list : /* empty */ | expression_list ; expression_list : exp | expression_list comma exp | error | expression_list error | expression_list error exp | expression_list comma error ; /* Expressions, not including the comma operator. */ exp : variable ASSIGNOP {} exp | '(' expression_list r_paren LEX_IN NAME | exp '|' LEX_GETLINE opt_variable | exp TWOWAYIO LEX_GETLINE opt_variable | LEX_GETLINE opt_variable input_redir | exp LEX_AND exp | exp LEX_OR exp | exp MATCHOP exp | regexp | '!' regexp %prec UNARY | exp LEX_IN NAME | exp RELOP exp | exp '<' exp | exp '>' exp | exp '?' exp ':' exp | simp_exp | exp simp_exp %prec CONCAT_OP ; rexp : variable ASSIGNOP {} rexp | rexp LEX_AND rexp | rexp LEX_OR rexp | LEX_GETLINE opt_variable input_redir | regexp | '!' regexp %prec UNARY | rexp MATCHOP rexp | rexp LEX_IN NAME | rexp RELOP rexp | rexp '?' rexp ':' rexp | simp_exp | rexp simp_exp %prec CONCAT_OP ; simp_exp : non_post_simp_exp /* Binary operators in order of decreasing precedence. */ | simp_exp '^' simp_exp | simp_exp '*' simp_exp | simp_exp '/' simp_exp | simp_exp '%' simp_exp | simp_exp '+' simp_exp | simp_exp '-' simp_exp | variable INCREMENT | variable DECREMENT ; non_post_simp_exp : '!' simp_exp %prec UNARY | '(' exp r_paren | LEX_BUILTIN '(' opt_expression_list r_paren | LEX_LENGTH '(' opt_expression_list r_paren | LEX_LENGTH | FUNC_CALL '(' opt_expression_list r_paren | variable | INCREMENT variable | DECREMENT variable | YNUMBER | YSTRING | '-' simp_exp %prec UNARY | '+' simp_exp %prec UNARY ; opt_variable : /* empty */ | variable ; variable : NAME | NAME '[' expression_list ']' | '$' non_post_simp_exp ; l_brace : '{' opt_nls ; r_brace : '}' opt_nls ; r_paren : ')' ; opt_semi : /* empty */ | semi ; semi : ';' ; comma : ',' opt_nls ; %% ]]) # Pass plenty of options, to exercise plenty of code, even if we # don't actually check the output. But SEGV is watching us, and # so might do dmalloc. AT_CHECK([[bison --verbose --defines input.y]]) AT_CLEANUP ## ----------------- ## ## GNU Cim Grammar. ## ## ----------------- ## AT_SETUP([GNU Cim Grammar]) # GNU Cim, the GNU Simula 87 Compiler. # Bison was once wrong, due to an incorrect computation of the RR conflicts. # It reported 80 SR && 99 RR conflicts instead of 78/10!!! AT_DATA([[input.y]], [[%union { long token; long ival; long arrdim; double rval; char *ident; char *tval; char stat_decl; } %token HACTIVATE HAFTER /*HAND*/ HARRAY HAT HBEFORE HBEGIN HBOOLEAN HCHARACTER HCLASS /*HCOMMENT*/ HCONC HDELAY HDO HELSE HEND HEQ /*HEQV*/ HEXTERNAL HFOR HGE HGO HGOTO HGT HHIDDEN HIF /*HIMP*/ HIN HINNER HINSPECT HINTEGER HIS HLABEL HLE HLONG HLT HNAME HNE HNEW HNONE /*HNOT*/ HNOTEXT /*HOR*/ HOTHERWISE HPRIOR HPROCEDURE HPROTECTED HQUA HREACTIVATE HREAL HREF HSHORT HSTEP HSWITCH HTEXT HTHEN HTHIS HTO HUNTIL HVALUE HVAR HVIRTUAL HWHEN HWHILE HASSIGNVALUE HASSIGNREF /*HDOT*/ HPAREXPSEPARATOR HLABELSEPARATOR HSTATEMENTSEPARATOR HBEGPAR HENDPAR HEQR HNER HADD HSUB HMUL HDIV HINTDIV HEXP HDOTDOTDOT %token HIDENTIFIER %token HBOOLEANKONST HINTEGERKONST HCHARACTERKONST %token HREALKONST %token HTEXTKONST %type EXT_IDENT %type DECLSTATEMENT MODULSTATEMENT MBEE_DECLSTMS MBEE_DECLSTMSU %type MODULS %type EXPRESSION_SIMP MBEE_ARG_R_PT %type BAUND_PAIR_LIST %right HASSIGN %left HORELSE %left HANDTHEN %left HEQV %left HIMP %left HOR %left HAND %left HNOT %left HVALRELOPERATOR HREFRELOPERATOR HOBJRELOPERATOR %left HCONC %left HTERMOPERATOR %left UNEAR %left HFACTOROPERATOR %left HPRIMARYOPERATOR %left HQUA %left HDOT %start MAIN_MODULE %% /* GRAMATIKK FOR PROGRAM MODULES */ MAIN_MODULE : { categ=CLOCAL; mout(MBLOCK); beginBlock(KBLOKK);separat_comp=FALSE;} MODULS { endBlock(NULL,CCNO); mout(MENDBLOCK);} | error HSTATEMENTSEPARATOR MBEE_DECLSTMS ; EXT_DECLARATION : HEXTERNAL MBEE_TYPE HPROCEDURE { MBEENEWBLOCK(); kind=KPROC;} EXT_LIST | HEXTERNAL HIDENTIFIER HPROCEDURE { MBEENEWBLOCK(); type=TNOTY; kind=KPROC; if($2==Ckind)categ=CCPROC;else yerror (1); ysensitive=sensitive; sensitive=ON;} HIDENTIFIER { $$=$5; sensitive=ysensitive;} EXTERNAL_KIND_ITEM { categ=CLOCAL;} | HEXTERNAL HCLASS { MBEENEWBLOCK(); kind=KCLASS;} EXT_LIST ; EXTERNAL_KIND_ITEM: EXT_IDENT HOBJRELOPERATOR { if($2!=HIS)yerror (2);} MBEE_TYPE HPROCEDURE HIDENTIFIER { regDecl($6, type, KPROC, CCPROC); beginBlock(kind);} HEADING EMPTY_BLOCK { categ=CLOCAL; endBlock($1==NULL?$0:tag($1),CCCPROC);} /* | EXT_IDENT { if($1!=NULL)yerror (3); regDecl($0, type, kind, categ);} MBEE_REST_EXT_LIST { endBlock(NULL,CCNO);} ; MBEE_REST_EXT_LIST: /* EMPTY | HPAREXPSEPARATOR EXT_KIND_LIST ; EXT_KIND_LIST : EXT_KIND_ITEM | EXT_KIND_LIST HPAREXPSEPARATOR EXT_KIND_ITEM ; EXT_KIND_ITEM : HIDENTIFIER EXT_IDENT { if($2!=NULL)yerror (3); regDecl($1, type, kind, categ);}*/ ; EMPTY_BLOCK : /*EMPT*/ | HBEGIN HEND ; EXT_LIST : EXT_ITEM | EXT_LIST HPAREXPSEPARATOR EXT_ITEM ; EXT_ITEM : HIDENTIFIER EXT_IDENT { lesinn_external_spec($1,$2, kind);} ; EXT_IDENT : /* EMPTY */ { $$=NULL;} | HVALRELOPERATOR { if($1!=HEQ)yerror (9); external=TRUE;} HTEXTKONST { $$=$3;external=FALSE;} ; /* GRAMATIKK FOR TYPER */ NO_TYPE : /*EMPT*/ { type=TNOTY;} ; MBEE_TYPE : NO_TYPE | TYPE ; TYPE : HREF HBEGPAR HIDENTIFIER { prefquantident=$3; type=TREF;} HENDPAR | HTEXT { type=TTEXT;} | HBOOLEAN { type=TBOOL;} | HCHARACTER { type=TCHAR;} | HSHORT HINTEGER { type=TSHORT;} | HINTEGER { type=TINTG;} | HREAL { type=TREAL;} | HLONG HREAL { type=TLONG;} ; /* GRAMATIKK FOR DEL AV SETNINGER */ MBEE_ELSE_PART : /*EMPT*/ /* | HELSE HIF EXPRESSION HTHEN { mout(MELSE); mout(MIF); OBSBLOCK();} BLOCK { MBEEENDBLOCK();} MBEE_ELSE_PART { mout(MENDIF);}*/ | HELSE { OBSBLOCK(); mout(MELSE);} BLOCK { MBEEENDBLOCK();} ; FOR_LIST : FOR_LIST_ELEMENT { mout(MENDSEP); mout(MLISTSEP);} | FOR_LIST_ELEMENT HPAREXPSEPARATOR FOR_LIST { mout(MLISTSEP);} ; FOR_LIST_ELEMENT: EXPRESSION MBEE_F_L_EL_R_PT ; MBEE_F_L_EL_R_PT: /*EMPT*/ | HWHILE EXPRESSION { mout(MFORWHILE);} | HSTEP EXPRESSION HUNTIL EXPRESSION { mout(MUNTIL); mout(MSTEP);} ; GOTO : HGO HTO | HGOTO ; CONN_STATE_R_PT : WHEN_CLAUSE_LIST | HDO { beginBlock(KCON); mout(MDO); OBSBLOCK(); } BLOCK { endBlock(NULL,CCNO); MBEEENDBLOCK(); mout(MENDDO);} ; WHEN_CLAUSE_LIST: HWHEN HIDENTIFIER HDO { beginBlock(KCON); mout(MIDENTIFIER); OBSBLOCK(); moutId($2); mout(MWHEN);} BLOCK { endBlock(NULL,CCNO); MBEEENDBLOCK(); mout(MENDWHEN);} | WHEN_CLAUSE_LIST HWHEN HIDENTIFIER HDO { beginBlock(KCON); mout(MIDENTIFIER); OBSBLOCK(); moutId($3); mout(MWHEN);} BLOCK { endBlock(NULL,CCNO); MBEEENDBLOCK(); mout(MENDWHEN);} ; MBEE_OTWI_CLAUS : /*EMPT*/ | HOTHERWISE {OBSBLOCK(); mout(MOTHERWISE);} BLOCK {MBEEENDBLOCK();mout(MENDOTHERWISE);} ; ACTIVATOR : HACTIVATE { mout(MBOOLEANKONST); moutIval(FALSE);} | HREACTIVATE { mout(MBOOLEANKONST); moutIval(TRUE);} ; SCHEDULE : /*EMPT*/ { mout(MCHARACTERKONST); moutIval(DIRECT); mout(MINTEGERKONST); moutIval(0); mout(MNONE); mout(MBOOLEANKONST); moutIval(FALSE);} | ATDELAY EXPRESSION { mout(MNONE);} PRIOR | BEFOREAFTER { mout(MINTEGERKONST); moutIval(0);} EXPRESSION { mout(MBOOLEANKONST); moutIval(FALSE);} ; ATDELAY : HAT { mout(MCHARACTERKONST); moutIval(AT);} | HDELAY { mout(MCHARACTERKONST); moutIval(DELAYS);} ; BEFOREAFTER : HBEFORE { mout(MCHARACTERKONST); moutIval(BEFORE);} | HAFTER { mout(MCHARACTERKONST); moutIval(AFTER);} ; PRIOR : /*EMPT*/ { mout(MBOOLEANKONST); moutIval(FALSE);} | HPRIOR { mout(MBOOLEANKONST); moutIval(TRUE);} ; /* GRAMATIKK FOR SETNINGER OG DEKLARASJONER */ MODULSTATEMENT : HWHILE EXPRESSION HDO { STOPOBSBLOCK(); mout(MWHILE); OBSBLOCK();} BLOCK { MBEEENDBLOCK(); mout(MENDWHILE); $$=STATEMENT;} | HIF EXPRESSION HTHEN { STOPOBSBLOCK(); mout(MIF); OBSBLOCK();} BLOCK { MBEEENDBLOCK();} MBEE_ELSE_PART { mout(MENDIF); $$=STATEMENT;} | HFOR HIDENTIFIER HASSIGN { STOPOBSBLOCK(); mout(MIDENTIFIER); moutId($2);} FOR_LIST HDO { beginBlock(KFOR); if($3==HASSIGNVALUE) mout(MFOR); else mout(MFORR); OBSBLOCK(); mout(MFORDO);} BLOCK { MBEEENDBLOCK(); endBlock(NULL,CCNO); mout(MENDFOR); $$=STATEMENT;} | GOTO EXPRESSION { mout(MGOTO); STOPOBSBLOCK(); $$=STATEMENT;} | HINSPECT EXPRESSION { mout(MINSPECT); STOPOBSBLOCK(); beginBlock(KINSP);} CONN_STATE_R_PT { endBlock(NULL,CCNO);} MBEE_OTWI_CLAUS { mout(MENDINSPECT); $$=STATEMENT;} | HINNER { STOPOBSBLOCK(); mout(MINNER); regInner(); $$=STATEMENT;} | HIDENTIFIER HLABELSEPARATOR { STOPOBSBLOCK(); regDecl($1, TLABEL, KSIMPLE, categ); mout(MLABEL); moutId($1); mout(MENDLABEL);} DECLSTATEMENT { if($4<=DECLARATION) { yerror (27); $$=DECLARATION;} else $$=$4;} | EXPRESSION_SIMP HBEGIN { $$=$1; } IMPORT_SPEC_MODULE { mout(MPRBLOCK); prefquantident=$1; beginBlock(KPRBLK);} MBEE_DECLSTMS HEND { endBlock(NULL,CCNO); mout(MENDPRBLOCK); $$=STATEMENT;} | EXPRESSION_SIMP HBEGIN error HSTATEMENTSEPARATOR MBEE_DECLSTMS HEND { $$=STATEMENT; endBlock(NULL,CCNO); mout(MENDPRBLOCK);} | EXPRESSION_SIMP HBEGIN error HEND { $$=STATEMENT; endBlock(NULL,CCNO); mout(MENDPRBLOCK);} | EXPRESSION_SIMP { STOPOBSBLOCK(); $$=STATEMENT; mout(MENDASSIGN);} | ACTIVATOR EXPRESSION SCHEDULE { $$=STATEMENT; mout(MENDSEP); mout(MARGUMENTSEP); mout(MARGUMENTSEP); mout(MARGUMENTSEP); mout(MARGUMENTSEP); mout(MARGUMENTSEP); mout(MARGUMENTSEP); mout(MARGUMENT); moutId(activateid); mout(MENDASSIGN);} | HBEGIN { STOPOBSBLOCK(); OBSBLOCK();} MBEE_DECLSTMS HEND { MBEEENDBLOCK(); $$=STATEMENT;} | MBEE_TYPE HPROCEDURE HIDENTIFIER { MBEENEWBLOCK(); mout(MPROCEDURE); regDecl($3, type, KPROC, categ); beginBlock(KPROC);} HEADING BLOCK { endBlock(NULL,CCNO); $$=DECLARATION; mout(MENDPROCEDURE);} | HIDENTIFIER HCLASS NO_TYPE { $$=$1; } IMPORT_SPEC_MODULE HIDENTIFIER { prefquantident=$1; mout(MCLASS); regDecl($6, TNOTY, KCLASS, categ); beginBlock(KCLASS);} HEADING BLOCK { endBlock(NULL,CCNO); $$=DECLARATION; mout(MENDCLASS);} | HCLASS NO_TYPE HIDENTIFIER { prefquantident=0; MBEENEWBLOCK(); mout(MCLASS); regDecl($3, TNOTY, KCLASS, categ); beginBlock(KCLASS);} HEADING BLOCK { endBlock(NULL,CCNO); $$=DECLARATION; mout(MENDCLASS);} | EXT_DECLARATION { $$=EXTDECLARATION;} | /*EMPT*/{ STOPOBSBLOCK(); $$=EMPTYSTATEMENT;} ; IMPORT_SPEC_MODULE: { MBEENEWBLOCK(); kind=KCLASS; if($0==simsetident && findDecl(simsetident,cblock,FALSE)==NULL) lesinn_external_spec(simsetident, SIMSETATRFILE, kind); if($0==simulationident && findDecl( simulationident,cblock,FALSE)==NULL) lesinn_external_spec(simulationident, SIMULATIONATRFILE, kind); if(($0==fileident && findDecl( fileident,cblock,FALSE)==NULL) || ($0==outfileident && findDecl( outfileident,cblock,FALSE)==NULL) || ($0==infileident && findDecl( infileident,cblock,FALSE)==NULL) || ($0==directfileident && findDecl( directfileident,cblock,FALSE)==NULL) || ($0==printfileident && findDecl( printfileident,cblock,FALSE)==NULL) || ($0==bytefileident && findDecl( bytefileident,cblock,FALSE)==NULL) || ($0==inbytefileident && findDecl( inbytefileident,cblock,FALSE)==NULL) || ($0==outbytefileident && findDecl( outbytefileident,cblock,FALSE)==NULL) || ($0==directbytefileident && findDecl( directbytefileident,cblock,FALSE)==NULL)) lesinn_external_spec(fileident, FILEATRFILE, kind);} ; DECLSTATEMENT : MODULSTATEMENT | TYPE HIDENTIFIER MBEE_CONSTANT HPAREXPSEPARATOR { MBEENEWBLOCK(); kind=KSIMPLE; regDecl($2, type, KSIMPLE, categ); categ=CLOCAL;} IDENTIFIER_LISTC { $$=DECLARATION;} | TYPE HIDENTIFIER MBEE_CONSTANT { MBEENEWBLOCK(); regDecl($2, type, KSIMPLE, categ); categ=CLOCAL; $$=DECLARATION;} | MBEE_TYPE HARRAY { MBEENEWBLOCK(); kind=KARRAY;} ARR_SEGMENT_LIST { $$=DECLARATION;} | HSWITCH HIDENTIFIER HASSIGN { MBEENEWBLOCK(); mout(MIDENTIFIER); moutId($2); regDecl($2, TLABEL, KARRAY, categ);} SWITCH_LIST { $$=DECLARATION; mout(MSWITCH); mout(MENDSWITCH);} ; BLOCK : DECLSTATEMENT { if($1<=DECLARATION)yerror (29);} | HBEGIN MBEE_DECLSTMS HEND | HBEGIN error HSTATEMENTSEPARATOR MBEE_DECLSTMS HEND | HBEGIN error HEND ; MBEE_DECLSTMS : MBEE_DECLSTMSU { if($1<=DECLARATION)yerror (28); $$=$1;} ; MBEE_DECLSTMSU : DECLSTATEMENT { $$=$1;} | MBEE_DECLSTMSU HSTATEMENTSEPARATOR DECLSTATEMENT { if($1>=STATEMENT && $3<=DECLARATION) yerror (26); $$=$3;} ; MODULS : MODULSTATEMENT { if($1==DECLARATION) {separat_comp=TRUE;gettimestamp();} $$=$1;} | MODULS HSTATEMENTSEPARATOR MODULSTATEMENT { if($1>=STATEMENT && $3<=DECLARATION) yerror (26);else if($1>=STATEMENT && $3!=EMPTYSTATEMENT)yerror (25); if(separat_comp && $3==STATEMENT) yerror (25); if($3==DECLARATION && !separat_comp) {separat_comp=TRUE;gettimestamp();} $$=$3;} ; /* GRAMATIKK FOR DEL AV DEKLARASJONER */ ARR_SEGMENT_LIST: ARR_SEGMENT | ARR_SEGMENT_LIST HPAREXPSEPARATOR ARR_SEGMENT ; ARR_SEGMENT : ARRAY_SEGMENT HBEGPAR BAUND_PAIR_LIST HENDPAR { mout(MARRAY); mout(MENDARRAY); setArrayDim($3);} ; ARRAY_SEGMENT : ARRAY_SEGMENT_EL { mout(MENDSEP); mout(MARRAYSEP);} | ARRAY_SEGMENT_EL HPAREXPSEPARATOR ARRAY_SEGMENT { mout(MARRAYSEP);} ; ARRAY_SEGMENT_EL: HIDENTIFIER { mout(MIDENTIFIER); moutId($1); regDecl($1, type, kind, categ); if(lastArray==NULL) lastArray=cblock->lastparloc;} ; BAUND_PAIR_LIST : BAUND_PAIR { mout(MENDSEP); mout(MBOUNDSEP); $$=1;} | BAUND_PAIR HPAREXPSEPARATOR BAUND_PAIR_LIST { mout(MBOUNDSEP); $$=$3+1;} ; BAUND_PAIR : EXPRESSION HLABELSEPARATOR EXPRESSION { mout(MBOUNDPARSEP);} ; SWITCH_LIST : EXPRESSION { mout(MENDSEP); mout(MSWITCHSEP);} | EXPRESSION HPAREXPSEPARATOR SWITCH_LIST { mout(MSWITCHSEP);} ; HEADING : MBEE_FMAL_PAR_P HSTATEMENTSEPARATOR { kind=KNOKD;} MBEE_MODE_PART { categ=CSPEC;} MBEE_SPEC_PART { kind=KNOKD;} MBEE_PROT_PART { categ=CVIRT;} MBEE_VIRT_PART { categ=CLOCAL;} ; MBEE_FMAL_PAR_P : /*EMPT*/ | FMAL_PAR_PART ; FMAL_PAR_PART : HBEGPAR NO_TYPE MBEE_LISTV HENDPAR ; MBEE_LISTV : /*EMPT*/ | LISTV ; LISTV : HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);} | FPP_CATEG HDOTDOTDOT { regDecl(varargsid, TVARARGS, KNOKD, categ);} | HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);} HPAREXPSEPARATOR LISTV | FPP_SPEC | FPP_SPEC HPAREXPSEPARATOR LISTV ; FPP_HEADING : HBEGPAR NO_TYPE FPP_MBEE_LISTV HENDPAR ; FPP_MBEE_LISTV : /*EMPT*/ | FPP_LISTV ; FPP_LISTV : FPP_CATEG HDOTDOTDOT { regDecl(varargsid, TVARARGS, KNOKD, categ);} | FPP_SPEC | FPP_SPEC HPAREXPSEPARATOR LISTV ; FPP_SPEC : FPP_CATEG SPECIFIER HIDENTIFIER { regDecl($3, type, kind, categ);} | FPP_CATEG FPP_PROC_DECL_IN_SPEC ; FPP_CATEG : HNAME HLABELSEPARATOR { categ=CNAME;} | HVALUE HLABELSEPARATOR { categ=CVALUE;} | HVAR HLABELSEPARATOR { categ=CVAR;} | /*EMPT*/ { categ=CDEFLT;} ; FPP_PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE HIDENTIFIER { $$=categ; regDecl($3, type, KPROC, categ); beginBlock(KPROC);} FPP_HEADING { categ=$4; /* M} settes tilbake*/} { endBlock(NULL,CCNO);} ; IDENTIFIER_LISTV: HIDENTIFIER { regDecl($1, type, kind, categ);} | HDOTDOTDOT { regDecl(varargsid, TVARARGS, kind, categ);} | HIDENTIFIER { regDecl($1, type, kind, categ);} HPAREXPSEPARATOR IDENTIFIER_LISTV ; MBEE_MODE_PART : /*EMPT*/ | MODE_PART ; MODE_PART : NAME_PART | VALUE_PART | VAR_PART | NAME_PART VALUE_PART | VALUE_PART NAME_PART | NAME_PART VAR_PART | VAR_PART NAME_PART | VALUE_PART VAR_PART | VAR_PART VALUE_PART | VAR_PART NAME_PART VALUE_PART | NAME_PART VAR_PART VALUE_PART | NAME_PART VALUE_PART VAR_PART | VAR_PART VALUE_PART NAME_PART | VALUE_PART VAR_PART NAME_PART | VALUE_PART NAME_PART VAR_PART ; NAME_PART : HNAME { categ=CNAME;} IDENTIFIER_LISTV HSTATEMENTSEPARATOR ; VAR_PART : HVAR { categ=CVAR;} IDENTIFIER_LISTV HSTATEMENTSEPARATOR ; VALUE_PART : HVALUE { categ=CVALUE;} IDENTIFIER_LISTV HSTATEMENTSEPARATOR ; MBEE_SPEC_PART : /*EMPT*/ | SPEC_PART ; SPEC_PART : ONE_SPEC | SPEC_PART ONE_SPEC ; ONE_SPEC : SPECIFIER IDENTIFIER_LIST HSTATEMENTSEPARATOR | NO_TYPE HPROCEDURE HIDENTIFIER HOBJRELOPERATOR { if($4!=HIS) yerror (8);} PROC_DECL_IN_SPEC HSTATEMENTSEPARATOR | FPP_PROC_DECL_IN_SPEC HSTATEMENTSEPARATOR | MBEE_TYPE HPROCEDURE HIDENTIFIER HSTATEMENTSEPARATOR { yerror (45);} | MBEE_TYPE HPROCEDURE HIDENTIFIER HPAREXPSEPARATOR IDENTIFIER_LIST HSTATEMENTSEPARATOR { yerror (45);} ; SPECIFIER : TYPE { kind=KSIMPLE;} | MBEE_TYPE HARRAY { kind=KARRAY;} | HLABEL { type=TLABEL; kind=KSIMPLE;} | HSWITCH { type=TLABEL; kind=KARRAY;} ; PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE HIDENTIFIER { $$=categ; regDecl($3, type, KPROC, categ); beginBlock(KPROC);} HEADING { categ=$4; /* M} settes tilbake*/} MBEE_BEGIN_END { endBlock(NULL,CCNO);} ; MBEE_BEGIN_END : /* EMPTY */ | HBEGIN HEND ; MBEE_PROT_PART : /*EMPT*/ | PROTECTION_PART ; PROTECTION_PART : PROT_SPECIFIER IDENTIFIER_LIST HSTATEMENTSEPARATOR | PROTECTION_PART PROT_SPECIFIER IDENTIFIER_LIST HSTATEMENTSEPARATOR ; PROT_SPECIFIER : HHIDDEN { categ=CHIDEN;} | HPROTECTED { categ=CPROT;} | HHIDDEN HPROTECTED { categ=CHIPRO;} | HPROTECTED HHIDDEN { categ=CHIPRO;} ; MBEE_VIRT_PART : /*EMPT*/ | VIRTUAL_PART ; VIRTUAL_PART : HVIRTUAL HLABELSEPARATOR MBEE_SPEC_PART ; IDENTIFIER_LIST : HIDENTIFIER { regDecl($1, type, kind, categ);} | IDENTIFIER_LIST HPAREXPSEPARATOR HIDENTIFIER { regDecl($3, type, kind, categ);} ; IDENTIFIER_LISTC: HIDENTIFIER MBEE_CONSTANT { regDecl($1, type, kind, categ); categ=CLOCAL;} | IDENTIFIER_LISTC HPAREXPSEPARATOR HIDENTIFIER MBEE_CONSTANT { regDecl($3, type, kind, categ); categ=CLOCAL;} ; MBEE_CONSTANT : /* EMPTY */ | HVALRELOPERATOR { MBEENEWBLOCK(); if($1!=HEQ) yerror (8); if(type==TREF)yerror (7); categ=CCONSTU; mout(MIDENTIFIER); moutId($0);} EXPRESSION { mout(MASSIGN); mout(MCONST);} ; /* GRAMATIKK FOR UTTRYKK */ EXPRESSION : EXPRESSION_SIMP {} | HIF EXPRESSION HTHEN EXPRESSION HELSE EXPRESSION { mout(MELSEE); mout(MIFE);} ; EXPRESSION_SIMP : EXPRESSION_SIMP HASSIGN EXPRESSION { if($2==HASSIGNREF)mout(MASSIGNR); else mout(MASSIGN);$$=NULL;} | EXPRESSION_SIMP HCONC EXPRESSION_SIMP { mout(MCONC);$$=NULL;} | EXPRESSION_SIMP HOR HELSE EXPRESSION_SIMP %prec HORELSE { mout(MORELSEE);$$=NULL;} | EXPRESSION_SIMP HAND HTHEN EXPRESSION_SIMP %prec HANDTHEN { mout(MANDTHENE);$$=NULL;} | EXPRESSION_SIMP HEQV EXPRESSION_SIMP { mout(MEQV);$$=NULL;} | EXPRESSION_SIMP HIMP EXPRESSION_SIMP { mout(MIMP);$$=NULL;} | EXPRESSION_SIMP HOR EXPRESSION_SIMP { mout(MOR);$$=NULL;} | EXPRESSION_SIMP HAND EXPRESSION_SIMP { mout(MAND);$$=NULL;} | HNOT EXPRESSION_SIMP { mout(MNOT);$$=NULL;} | EXPRESSION_SIMP HVALRELOPERATOR EXPRESSION_SIMP { switch($2) { case HEQ: mout(MEQ);break; case HNE: mout(MNE);break; case HLT: mout(MLT);break; case HLE: mout(MLE);break; case HGT: mout(MGT);break; case HGE: mout(MGE);break; }; $$=NULL;} | EXPRESSION_SIMP HREFRELOPERATOR EXPRESSION_SIMP { if($2==HNER) mout(MNER); else mout(MEQR);$$=NULL;} | EXPRESSION_SIMP HOBJRELOPERATOR EXPRESSION_SIMP { if($2==HIS) mout(MIS); else mout(MINS);$$=NULL;} | HTERMOPERATOR EXPRESSION_SIMP %prec UNEAR { if($1==HADD) mout(MUADD); else mout(MUSUB);$$=NULL;} | EXPRESSION_SIMP HTERMOPERATOR EXPRESSION_SIMP { if($2==HADD) mout(MADD); else mout(MSUB);$$=NULL;} | EXPRESSION_SIMP HFACTOROPERATOR EXPRESSION_SIMP { if($2==HMUL) mout(MMUL); else if($2==HDIV) mout(MDIV); else mout(MINTDIV);$$=NULL;} | EXPRESSION_SIMP HPRIMARYOPERATOR EXPRESSION_SIMP { mout(MPRIMARY);$$=NULL;} | HBEGPAR EXPRESSION HENDPAR { mout(MNOOP);$$=NULL;} | HTEXTKONST { mout(MTEXTKONST); moutTval($1);$$=NULL;} | HCHARACTERKONST { mout(MCHARACTERKONST); moutIval($1);$$=NULL;} | HREALKONST { mout(MREALKONST); moutRval($1);$$=NULL;} | HINTEGERKONST { mout(MINTEGERKONST); moutIval($1);$$=NULL;} | HBOOLEANKONST { mout(MBOOLEANKONST); moutIval($1);$$=NULL;} | HNONE { mout(MNONE);$$=NULL;} | HIDENTIFIER { $$=$1;} MBEE_ARG_R_PT | HTHIS HIDENTIFIER { mout(MTHIS); moutId($2);$$=NULL;} | HNEW HIDENTIFIER ARG_R_PT { mout(MNEWARG); moutId($2);$$=NULL;} | EXPRESSION_SIMP HDOT EXPRESSION_SIMP { mout(MDOT);$$=NULL;} | EXPRESSION_SIMP HQUA HIDENTIFIER { mout(MQUA); moutId($3);$$=NULL;} ; ARG_R_PT : /*EMPTY*/ { mout(MENDSEP);} | HBEGPAR ARGUMENT_LIST HENDPAR ; MBEE_ARG_R_PT : /*EMPTY*/ { mout(MIDENTIFIER); moutId($0); $$=$0;} | HBEGPAR ARGUMENT_LIST HENDPAR { mout(MARGUMENT); moutId($0);} ; ARGUMENT_LIST : EXPRESSION { mout(MENDSEP); mout(MARGUMENTSEP);} | EXPRESSION HPAREXPSEPARATOR ARGUMENT_LIST { mout(MARGUMENTSEP);} ; %% ]]) # Pass plenty of options, to exercise plenty of code, even if we # don't actually check the output. But SEGV is watching us, and # so might do dmalloc. AT_CHECK([[bison --verbose --defines input.y]], 0, [], [[input.y contains 78 shift/reduce conflicts and 10 reduce/reduce conflicts. ]]) AT_CHECK([[grep '^State.*contains' input.output]], 0, [[State 64 contains 14 shift/reduce conflicts. State 164 contains 1 shift/reduce conflict. State 201 contains 33 shift/reduce conflicts and 4 reduce/reduce conflicts. State 206 contains 1 shift/reduce conflict. State 240 contains 1 shift/reduce conflict. State 335 contains 9 shift/reduce conflicts and 2 reduce/reduce conflicts. State 356 contains 1 shift/reduce conflict. State 360 contains 9 shift/reduce conflicts and 2 reduce/reduce conflicts. State 427 contains 9 shift/reduce conflicts and 2 reduce/reduce conflicts. ]]) AT_CLEANUP