1 /* Driver template for the LEMON parser generator. 2 ** The author disclaims copyright to this source code. 3 */ 4 /* First off, code is include which follows the "include" declaration 5 ** in the input file. */ 6 #include <stdio.h> 7 #line 6 "./mod_ssi_exprparser.y" 8 9 #include "mod_ssi_expr.h" 10 #include "buffer.h" 11 12 #include <assert.h> 13 #include <string.h> 14 15 #line 16 "mod_ssi_exprparser.c" 16 /* Next is all token values, in a form suitable for use by makeheaders. 17 ** This section will be null unless lemon is run with the -m switch. 18 */ 19 /* 20 ** These constants (all generated automatically by the parser generator) 21 ** specify the various kinds of tokens (terminals) that the parser 22 ** understands. 23 ** 24 ** Each symbol here is a terminal symbol in the grammar. 25 */ 26 /* Make sure the INTERFACE macro is defined. 27 */ 28 #ifndef INTERFACE 29 # define INTERFACE 1 30 #endif 31 /* The next thing included is series of defines which control 32 ** various aspects of the generated parser. 33 ** YYCODETYPE is the data type used for storing terminal 34 ** and nonterminal numbers. "unsigned char" is 35 ** used if there are fewer than 250 terminals 36 ** and nonterminals. "int" is used otherwise. 37 ** YYNOCODE is a number of type YYCODETYPE which corresponds 38 ** to no legal terminal or nonterminal number. This 39 ** number is used to fill in empty slots of the hash 40 ** table. 41 ** YYFALLBACK If defined, this indicates that one or more tokens 42 ** have fall-back values which should be used if the 43 ** original value of the token will not parse. 44 ** YYACTIONTYPE is the data type used for storing terminal 45 ** and nonterminal numbers. "unsigned char" is 46 ** used if there are fewer than 250 rules and 47 ** states combined. "int" is used otherwise. 48 ** ssiexprparserTOKENTYPE is the data type used for minor tokens given 49 ** directly to the parser from the tokenizer. 50 ** YYMINORTYPE is the data type used for all minor tokens. 51 ** This is typically a union of many types, one of 52 ** which is ssiexprparserTOKENTYPE. The entry in the union 53 ** for base tokens is called "yy0". 54 ** YYSTACKDEPTH is the maximum depth of the parser's stack. 55 ** ssiexprparserARG_SDECL A static variable declaration for the %extra_argument 56 ** ssiexprparserARG_PDECL A parameter declaration for the %extra_argument 57 ** ssiexprparserARG_STORE Code to store %extra_argument into yypParser 58 ** ssiexprparserARG_FETCH Code to extract %extra_argument from yypParser 59 ** YYNSTATE the combined number of states. 60 ** YYNRULE the number of rules in the grammar 61 ** YYERRORSYMBOL is the code number of the error symbol. If not 62 ** defined, then do no error processing. 63 */ 64 /* */ 65 #define YYCODETYPE unsigned char 66 #define YYNOCODE 20 67 #define YYACTIONTYPE unsigned char 68 #define ssiexprparserTOKENTYPE buffer * 69 typedef union { 70 ssiexprparserTOKENTYPE yy0; 71 int yy8; 72 buffer * yy19; 73 ssi_val_t * yy29; 74 int yy39; 75 } YYMINORTYPE; 76 #define YYSTACKDEPTH 100 77 #define ssiexprparserARG_SDECL ssi_ctx_t *ctx; 78 #define ssiexprparserARG_PDECL ,ssi_ctx_t *ctx 79 #define ssiexprparserARG_FETCH ssi_ctx_t *ctx = yypParser->ctx 80 #define ssiexprparserARG_STORE yypParser->ctx = ctx 81 #define YYNSTATE 23 82 #define YYNRULE 16 83 #define YYERRORSYMBOL 13 84 #define YYERRSYMDT yy39 85 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) 86 #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) 87 #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) 88 89 /* Next are that tables used to determine what action to take based on the 90 ** current state and lookahead token. These tables are used to implement 91 ** functions that take a state number and lookahead value and return an 92 ** action integer. 93 ** 94 ** Suppose the action integer is N. Then the action is determined as 95 ** follows 96 ** 97 ** 0 <= N < YYNSTATE Shift N. That is, push the lookahead 98 ** token onto the stack and goto state N. 99 ** 100 ** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. 101 ** 102 ** N == YYNSTATE+YYNRULE A syntax error has occurred. 103 ** 104 ** N == YYNSTATE+YYNRULE+1 The parser accepts its input. 105 ** 106 ** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused 107 ** slots in the yy_action[] table. 108 ** 109 ** The action table is constructed as a single large table named yy_action[]. 110 ** Given state S and lookahead X, the action is computed as 111 ** 112 ** yy_action[ yy_shift_ofst[S] + X ] 113 ** 114 ** If the index value yy_shift_ofst[S]+X is out of range or if the value 115 ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] 116 ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table 117 ** and that yy_default[S] should be used instead. 118 ** 119 ** The formula above is for computing the action when the lookahead is 120 ** a terminal symbol. If the lookahead is a non-terminal (as occurs after 121 ** a reduce action) then the yy_reduce_ofst[] array is used in place of 122 ** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of 123 ** YY_SHIFT_USE_DFLT. 124 ** 125 ** The following are the tables generated in this section: 126 ** 127 ** yy_action[] A single table containing all actions. 128 ** yy_lookahead[] A table containing the lookahead for each entry in 129 ** yy_action. Used to detect hash collisions. 130 ** yy_shift_ofst[] For each state, the offset into yy_action for 131 ** shifting terminals. 132 ** yy_reduce_ofst[] For each state, the offset into yy_action for 133 ** shifting non-terminals after a reduce. 134 ** yy_default[] Default action for each state. 135 */ 136 static YYACTIONTYPE yy_action[] = { 137 /* 0 */ 5, 7, 17, 18, 22, 20, 21, 19, 2, 14, 138 /* 10 */ 1, 23, 40, 9, 11, 3, 16, 2, 14, 12, 139 /* 20 */ 4, 14, 5, 7, 6, 14, 7, 8, 14, 10, 140 /* 30 */ 14, 13, 37, 37, 15, 141 }; 142 static YYCODETYPE yy_lookahead[] = { 143 /* 0 */ 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 144 /* 10 */ 16, 0, 18, 9, 10, 17, 12, 14, 15, 16, 145 /* 20 */ 14, 15, 1, 2, 14, 15, 2, 14, 15, 14, 146 /* 30 */ 15, 11, 19, 19, 12, 147 }; 148 #define YY_SHIFT_USE_DFLT (-2) 149 static signed char yy_shift_ofst[] = { 150 /* 0 */ 4, 11, -1, 4, 21, 4, 24, 4, -2, 4, 151 /* 10 */ -2, 4, 20, -2, 22, -2, -2, -2, -2, -2, 152 /* 20 */ -2, -2, -2, 153 }; 154 #define YY_REDUCE_USE_DFLT (-7) 155 static signed char yy_reduce_ofst[] = { 156 /* 0 */ -6, -7, -2, 6, -7, 10, -7, 13, -7, 15, 157 /* 10 */ -7, 3, -7, -7, -7, -7, -7, -7, -7, -7, 158 /* 20 */ -7, -7, -7, 159 }; 160 static YYACTIONTYPE yy_default[] = { 161 /* 0 */ 39, 39, 25, 39, 24, 39, 26, 39, 27, 39, 162 /* 10 */ 28, 39, 39, 29, 30, 32, 31, 33, 34, 35, 163 /* 20 */ 36, 37, 38, 164 }; 165 #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) 166 167 /* The next table maps tokens into fallback tokens. If a construct 168 ** like the following: 169 ** 170 ** %fallback ID X Y Z. 171 ** 172 ** appears in the grammer, then ID becomes a fallback token for X, Y, 173 ** and Z. Whenever one of the tokens X, Y, or Z is input to the parser 174 ** but it does not parse, the type of the token is changed to ID and 175 ** the parse is retried before an error is thrown. 176 */ 177 #ifdef YYFALLBACK 178 static const YYCODETYPE yyFallback[] = { 179 }; 180 #endif /* YYFALLBACK */ 181 182 /* The following structure represents a single element of the 183 ** parser's stack. Information stored includes: 184 ** 185 ** + The state number for the parser at this level of the stack. 186 ** 187 ** + The value of the token stored at this level of the stack. 188 ** (In other words, the "major" token.) 189 ** 190 ** + The semantic value stored at this level of the stack. This is 191 ** the information used by the action routines in the grammar. 192 ** It is sometimes called the "minor" token. 193 */ 194 struct yyStackEntry { 195 int stateno; /* The state-number */ 196 int major; /* The major token value. This is the code 197 ** number for the token at this stack level */ 198 YYMINORTYPE minor; /* The user-supplied minor token value. This 199 ** is the value of the token */ 200 }; 201 typedef struct yyStackEntry yyStackEntry; 202 203 /* The state of the parser is completely contained in an instance of 204 ** the following structure */ 205 struct yyParser { 206 int yyidx; /* Index of top element in stack */ 207 int yyerrcnt; /* Shifts left before out of the error */ 208 ssiexprparserARG_SDECL /* A place to hold %extra_argument */ 209 yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ 210 }; 211 typedef struct yyParser yyParser; 212 213 #ifndef NDEBUG 214 #include <stdio.h> 215 static FILE *yyTraceFILE = NULL; 216 static char *yyTracePrompt = NULL; 217 #endif /* NDEBUG */ 218 219 #ifndef NDEBUG 220 /* 221 ** Turn parser tracing on by giving a stream to which to write the trace 222 ** and a prompt to preface each trace message. Tracing is turned off 223 ** by making either argument NULL 224 ** 225 ** Inputs: 226 ** <ul> 227 ** <li> A FILE* to which trace output should be written. 228 ** If NULL, then tracing is turned off. 229 ** <li> A prefix string written at the beginning of every 230 ** line of trace output. If NULL, then tracing is 231 ** turned off. 232 ** </ul> 233 ** 234 ** Outputs: 235 ** None. 236 */ 237 #if 0 238 void ssiexprparserTrace(FILE *TraceFILE, char *zTracePrompt){ 239 yyTraceFILE = TraceFILE; 240 yyTracePrompt = zTracePrompt; 241 if( yyTraceFILE==0 ) yyTracePrompt = 0; 242 else if( yyTracePrompt==0 ) yyTraceFILE = 0; 243 } 244 #endif 245 #endif /* NDEBUG */ 246 247 #ifndef NDEBUG 248 /* For tracing shifts, the names of all terminals and nonterminals 249 ** are required. The following table supplies these names */ 250 static const char *yyTokenName[] = { 251 "$", "AND", "OR", "EQ", 252 "NE", "GT", "GE", "LT", 253 "LE", "NOT", "LPARAN", "RPARAN", 254 "VALUE", "error", "expr", "value", 255 "exprline", "cond", "input", 256 }; 257 #endif /* NDEBUG */ 258 259 #ifndef NDEBUG 260 /* For tracing reduce actions, the names of all rules are required. 261 */ 262 static const char *yyRuleName[] = { 263 /* 0 */ "input ::= exprline", 264 /* 1 */ "exprline ::= expr cond expr", 265 /* 2 */ "exprline ::= expr", 266 /* 3 */ "expr ::= expr AND expr", 267 /* 4 */ "expr ::= expr OR expr", 268 /* 5 */ "expr ::= NOT expr", 269 /* 6 */ "expr ::= LPARAN exprline RPARAN", 270 /* 7 */ "expr ::= value", 271 /* 8 */ "value ::= VALUE", 272 /* 9 */ "value ::= value VALUE", 273 /* 10 */ "cond ::= EQ", 274 /* 11 */ "cond ::= NE", 275 /* 12 */ "cond ::= LE", 276 /* 13 */ "cond ::= GE", 277 /* 14 */ "cond ::= LT", 278 /* 15 */ "cond ::= GT", 279 }; 280 #endif /* NDEBUG */ 281 282 /* 283 ** This function returns the symbolic name associated with a token 284 ** value. 285 */ 286 #if 0 287 const char *ssiexprparserTokenName(int tokenType){ 288 #ifndef NDEBUG 289 if( tokenType>0 && (size_t)tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){ 290 return yyTokenName[tokenType]; 291 }else{ 292 return "Unknown"; 293 } 294 #else 295 return ""; 296 #endif 297 } 298 #endif 299 300 /* 301 ** This function allocates a new parser. 302 ** The only argument is a pointer to a function which works like 303 ** malloc. 304 ** 305 ** Inputs: 306 ** A pointer to the function used to allocate memory. 307 ** 308 ** Outputs: 309 ** A pointer to a parser. This pointer is used in subsequent calls 310 ** to ssiexprparser and ssiexprparserFree. 311 */ 312 void *ssiexprparserAlloc(void *(*mallocProc)(size_t)){ 313 yyParser *pParser; 314 pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); 315 if( pParser ){ 316 pParser->yyidx = -1; 317 } 318 return pParser; 319 } 320 321 /* The following function deletes the value associated with a 322 ** symbol. The symbol can be either a terminal or nonterminal. 323 ** "yymajor" is the symbol code, and "yypminor" is a pointer to 324 ** the value. 325 */ 326 static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ 327 switch( yymajor ){ 328 /* Here is inserted the actions which take place when a 329 ** terminal or non-terminal is destroyed. This can happen 330 ** when the symbol is popped from the stack during a 331 ** reduce or during error processing or when a parser is 332 ** being destroyed before it is finished parsing. 333 ** 334 ** Note: during a reduce, the only symbols destroyed are those 335 ** which appear on the RHS of the rule, but which are not used 336 ** inside the C code. 337 */ 338 case 1: 339 case 2: 340 case 3: 341 case 4: 342 case 5: 343 case 6: 344 case 7: 345 case 8: 346 case 9: 347 case 10: 348 case 11: 349 case 12: 350 #line 22 "./mod_ssi_exprparser.y" 351 { buffer_free((yypminor->yy0)); } 352 #line 352 "mod_ssi_exprparser.c" 353 break; 354 default: break; /* If no destructor action specified: do nothing */ 355 } 356 } 357 358 /* 359 ** Pop the parser's stack once. 360 ** 361 ** If there is a destructor routine associated with the token which 362 ** is popped from the stack, then call it. 363 ** 364 ** Return the major token number for the symbol popped. 365 */ 366 static int yy_pop_parser_stack(yyParser *pParser){ 367 YYCODETYPE yymajor; 368 yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; 369 370 if( pParser->yyidx<0 ) return 0; 371 #ifndef NDEBUG 372 if( yyTraceFILE && pParser->yyidx>=0 ){ 373 fprintf(yyTraceFILE,"%sPopping %s\n", 374 yyTracePrompt, 375 yyTokenName[yytos->major]); 376 } 377 #endif 378 yymajor = yytos->major; 379 yy_destructor( yymajor, &yytos->minor); 380 pParser->yyidx--; 381 return yymajor; 382 } 383 384 /* 385 ** Deallocate and destroy a parser. Destructors are all called for 386 ** all stack elements before shutting the parser down. 387 ** 388 ** Inputs: 389 ** <ul> 390 ** <li> A pointer to the parser. This should be a pointer 391 ** obtained from ssiexprparserAlloc. 392 ** <li> A pointer to a function used to reclaim memory obtained 393 ** from malloc. 394 ** </ul> 395 */ 396 void ssiexprparserFree( 397 void *p, /* The parser to be deleted */ 398 void (*freeProc)(void*) /* Function used to reclaim memory */ 399 ){ 400 yyParser *pParser = (yyParser*)p; 401 if( pParser==NULL ) return; 402 while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); 403 (*freeProc)((void*)pParser); 404 } 405 406 /* 407 ** Find the appropriate action for a parser given the terminal 408 ** look-ahead token iLookAhead. 409 ** 410 ** If the look-ahead token is YYNOCODE, then check to see if the action is 411 ** independent of the look-ahead. If it is, return the action, otherwise 412 ** return YY_NO_ACTION. 413 */ 414 static int yy_find_shift_action( 415 yyParser *pParser, /* The parser */ 416 int iLookAhead /* The look-ahead token */ 417 ){ 418 int i; 419 int stateno = pParser->yystack[pParser->yyidx].stateno; 420 421 /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */ 422 i = yy_shift_ofst[stateno]; 423 if( i==YY_SHIFT_USE_DFLT ){ 424 return yy_default[stateno]; 425 } 426 if( iLookAhead==YYNOCODE ){ 427 return YY_NO_ACTION; 428 } 429 i += iLookAhead; 430 if( i<0 || (size_t)i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ 431 #ifdef YYFALLBACK 432 int iFallback; /* Fallback token */ 433 if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0]) 434 && (iFallback = yyFallback[iLookAhead])!=0 ){ 435 #ifndef NDEBUG 436 if( yyTraceFILE ){ 437 fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", 438 yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); 439 } 440 #endif 441 return yy_find_shift_action(pParser, iFallback); 442 } 443 #endif 444 return yy_default[stateno]; 445 }else{ 446 return yy_action[i]; 447 } 448 } 449 450 /* 451 ** Find the appropriate action for a parser given the non-terminal 452 ** look-ahead token iLookAhead. 453 ** 454 ** If the look-ahead token is YYNOCODE, then check to see if the action is 455 ** independent of the look-ahead. If it is, return the action, otherwise 456 ** return YY_NO_ACTION. 457 */ 458 static int yy_find_reduce_action( 459 yyParser *pParser, /* The parser */ 460 int iLookAhead /* The look-ahead token */ 461 ){ 462 int i; 463 int stateno = pParser->yystack[pParser->yyidx].stateno; 464 465 i = yy_reduce_ofst[stateno]; 466 if( i==YY_REDUCE_USE_DFLT ){ 467 return yy_default[stateno]; 468 } 469 if( iLookAhead==YYNOCODE ){ 470 return YY_NO_ACTION; 471 } 472 i += iLookAhead; 473 if( i<0 || (size_t)i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ 474 return yy_default[stateno]; 475 }else{ 476 return yy_action[i]; 477 } 478 } 479 480 /* 481 ** Perform a shift action. 482 */ 483 static void yy_shift( 484 yyParser *yypParser, /* The parser to be shifted */ 485 int yyNewState, /* The new state to shift in */ 486 int yyMajor, /* The major token to shift in */ 487 YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */ 488 ){ 489 yyStackEntry *yytos; 490 yypParser->yyidx++; 491 if( yypParser->yyidx>=YYSTACKDEPTH ){ 492 ssiexprparserARG_FETCH; 493 yypParser->yyidx--; 494 #ifndef NDEBUG 495 if( yyTraceFILE ){ 496 fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); 497 } 498 #endif 499 while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); 500 /* Here code is inserted which will execute if the parser 501 ** stack every overflows */ 502 ssiexprparserARG_STORE; /* Suppress warning about unused %extra_argument var */ 503 return; 504 } 505 yytos = &yypParser->yystack[yypParser->yyidx]; 506 yytos->stateno = yyNewState; 507 yytos->major = yyMajor; 508 yytos->minor = *yypMinor; 509 #ifndef NDEBUG 510 if( yyTraceFILE && yypParser->yyidx>0 ){ 511 int i; 512 fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); 513 fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); 514 for(i=1; i<=yypParser->yyidx; i++) 515 fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); 516 fprintf(yyTraceFILE,"\n"); 517 } 518 #endif 519 } 520 521 /* The following table contains information about every rule that 522 ** is used during the reduce. 523 */ 524 static struct { 525 YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ 526 unsigned char nrhs; /* Number of right-hand side symbols in the rule */ 527 } yyRuleInfo[] = { 528 { 18, 1 }, 529 { 16, 3 }, 530 { 16, 1 }, 531 { 14, 3 }, 532 { 14, 3 }, 533 { 14, 2 }, 534 { 14, 3 }, 535 { 14, 1 }, 536 { 15, 1 }, 537 { 15, 2 }, 538 { 17, 1 }, 539 { 17, 1 }, 540 { 17, 1 }, 541 { 17, 1 }, 542 { 17, 1 }, 543 { 17, 1 }, 544 }; 545 546 static void yy_accept(yyParser*); /* Forward Declaration */ 547 548 /* 549 ** Perform a reduce action and the shift that must immediately 550 ** follow the reduce. 551 */ 552 static void yy_reduce( 553 yyParser *yypParser, /* The parser */ 554 int yyruleno /* Number of the rule by which to reduce */ 555 ){ 556 int yygoto; /* The next state */ 557 int yyact; /* The next action */ 558 YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ 559 yyStackEntry *yymsp; /* The top of the parser's stack */ 560 int yysize; /* Amount to pop the stack */ 561 ssiexprparserARG_FETCH; 562 yymsp = &yypParser->yystack[yypParser->yyidx]; 563 #ifndef NDEBUG 564 if( yyTraceFILE && yyruleno>=0 565 && (size_t)yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){ 566 fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, 567 yyRuleName[yyruleno]); 568 } 569 #endif /* NDEBUG */ 570 571 switch( yyruleno ){ 572 /* Beginning here are the reduction cases. A typical example 573 ** follows: 574 ** case 0: 575 ** #line <lineno> <grammarfile> 576 ** { ... } // User supplied code 577 ** #line <lineno> <thisfile> 578 ** break; 579 */ 580 case 0: 581 #line 29 "./mod_ssi_exprparser.y" 582 { 583 ctx->val.bo = ssi_val_tobool(yymsp[0].minor.yy29); 584 ctx->val.type = SSI_TYPE_BOOL; 585 586 ssi_val_free(yymsp[0].minor.yy29); 587 } 588 #line 588 "mod_ssi_exprparser.c" 589 break; 590 case 1: 591 #line 36 "./mod_ssi_exprparser.y" 592 { 593 int cmp; 594 595 if (yymsp[-2].minor.yy29->type == SSI_TYPE_STRING && 596 yymsp[0].minor.yy29->type == SSI_TYPE_STRING) { 597 cmp = strcmp(yymsp[-2].minor.yy29->str->ptr, yymsp[0].minor.yy29->str->ptr); 598 } else { 599 cmp = ssi_val_tobool(yymsp[-2].minor.yy29) - ssi_val_tobool(yymsp[0].minor.yy29); 600 } 601 602 yygotominor.yy29 = yymsp[-2].minor.yy29; 603 604 switch(yymsp[-1].minor.yy8) { 605 case SSI_COND_EQ: yygotominor.yy29->bo = (cmp == 0) ? 1 : 0; break; 606 case SSI_COND_NE: yygotominor.yy29->bo = (cmp != 0) ? 1 : 0; break; 607 case SSI_COND_GE: yygotominor.yy29->bo = (cmp >= 0) ? 1 : 0; break; 608 case SSI_COND_GT: yygotominor.yy29->bo = (cmp > 0) ? 1 : 0; break; 609 case SSI_COND_LE: yygotominor.yy29->bo = (cmp <= 0) ? 1 : 0; break; 610 case SSI_COND_LT: yygotominor.yy29->bo = (cmp < 0) ? 1 : 0; break; 611 } 612 613 yygotominor.yy29->type = SSI_TYPE_BOOL; 614 615 ssi_val_free(yymsp[0].minor.yy29); 616 } 617 #line 617 "mod_ssi_exprparser.c" 618 break; 619 case 2: 620 #line 61 "./mod_ssi_exprparser.y" 621 { 622 yygotominor.yy29 = yymsp[0].minor.yy29; 623 } 624 #line 624 "mod_ssi_exprparser.c" 625 break; 626 case 3: 627 #line 64 "./mod_ssi_exprparser.y" 628 { 629 int e; 630 631 e = ssi_val_tobool(yymsp[-2].minor.yy29) && ssi_val_tobool(yymsp[0].minor.yy29); 632 633 yygotominor.yy29 = yymsp[-2].minor.yy29; 634 yygotominor.yy29->bo = e; 635 yygotominor.yy29->type = SSI_TYPE_BOOL; 636 ssi_val_free(yymsp[0].minor.yy29); 637 } 638 #line 638 "mod_ssi_exprparser.c" 639 yy_destructor(1,&yymsp[-1].minor); 640 break; 641 case 4: 642 #line 75 "./mod_ssi_exprparser.y" 643 { 644 int e; 645 646 e = ssi_val_tobool(yymsp[-2].minor.yy29) || ssi_val_tobool(yymsp[0].minor.yy29); 647 648 yygotominor.yy29 = yymsp[-2].minor.yy29; 649 yygotominor.yy29->bo = e; 650 yygotominor.yy29->type = SSI_TYPE_BOOL; 651 ssi_val_free(yymsp[0].minor.yy29); 652 } 653 #line 653 "mod_ssi_exprparser.c" 654 yy_destructor(2,&yymsp[-1].minor); 655 break; 656 case 5: 657 #line 86 "./mod_ssi_exprparser.y" 658 { 659 int e; 660 661 e = !ssi_val_tobool(yymsp[0].minor.yy29); 662 663 yygotominor.yy29 = yymsp[0].minor.yy29; 664 yygotominor.yy29->bo = e; 665 yygotominor.yy29->type = SSI_TYPE_BOOL; 666 } 667 #line 667 "mod_ssi_exprparser.c" 668 yy_destructor(9,&yymsp[-1].minor); 669 break; 670 case 6: 671 #line 95 "./mod_ssi_exprparser.y" 672 { 673 yygotominor.yy29 = yymsp[-1].minor.yy29; 674 } 675 #line 675 "mod_ssi_exprparser.c" 676 yy_destructor(10,&yymsp[-2].minor); 677 yy_destructor(11,&yymsp[0].minor); 678 break; 679 case 7: 680 #line 99 "./mod_ssi_exprparser.y" 681 { 682 yygotominor.yy29 = ssi_val_init(); 683 yygotominor.yy29->str = yymsp[0].minor.yy19; 684 yygotominor.yy29->type = SSI_TYPE_STRING; 685 } 686 #line 686 "mod_ssi_exprparser.c" 687 break; 688 case 8: 689 #line 105 "./mod_ssi_exprparser.y" 690 { 691 yygotominor.yy19 = yymsp[0].minor.yy0; 692 } 693 #line 693 "mod_ssi_exprparser.c" 694 break; 695 case 9: 696 #line 109 "./mod_ssi_exprparser.y" 697 { 698 yygotominor.yy19 = yymsp[-1].minor.yy19; 699 buffer_append_string_buffer(yygotominor.yy19, yymsp[0].minor.yy0); 700 buffer_free(yymsp[0].minor.yy0); 701 } 702 #line 702 "mod_ssi_exprparser.c" 703 break; 704 case 10: 705 #line 115 "./mod_ssi_exprparser.y" 706 { yygotominor.yy8 = SSI_COND_EQ; } 707 #line 707 "mod_ssi_exprparser.c" 708 yy_destructor(3,&yymsp[0].minor); 709 break; 710 case 11: 711 #line 116 "./mod_ssi_exprparser.y" 712 { yygotominor.yy8 = SSI_COND_NE; } 713 #line 713 "mod_ssi_exprparser.c" 714 yy_destructor(4,&yymsp[0].minor); 715 break; 716 case 12: 717 #line 117 "./mod_ssi_exprparser.y" 718 { yygotominor.yy8 = SSI_COND_LE; } 719 #line 719 "mod_ssi_exprparser.c" 720 yy_destructor(8,&yymsp[0].minor); 721 break; 722 case 13: 723 #line 118 "./mod_ssi_exprparser.y" 724 { yygotominor.yy8 = SSI_COND_GE; } 725 #line 725 "mod_ssi_exprparser.c" 726 yy_destructor(6,&yymsp[0].minor); 727 break; 728 case 14: 729 #line 119 "./mod_ssi_exprparser.y" 730 { yygotominor.yy8 = SSI_COND_LT; } 731 #line 731 "mod_ssi_exprparser.c" 732 yy_destructor(7,&yymsp[0].minor); 733 break; 734 case 15: 735 #line 120 "./mod_ssi_exprparser.y" 736 { yygotominor.yy8 = SSI_COND_GT; } 737 #line 737 "mod_ssi_exprparser.c" 738 yy_destructor(5,&yymsp[0].minor); 739 break; 740 }; 741 yygoto = yyRuleInfo[yyruleno].lhs; 742 yysize = yyRuleInfo[yyruleno].nrhs; 743 yypParser->yyidx -= yysize; 744 yyact = yy_find_reduce_action(yypParser,yygoto); 745 if( yyact < YYNSTATE ){ 746 yy_shift(yypParser,yyact,yygoto,&yygotominor); 747 }else if( yyact == YYNSTATE + YYNRULE + 1 ){ 748 yy_accept(yypParser); 749 } 750 } 751 752 /* 753 ** The following code executes when the parse fails 754 */ 755 static void yy_parse_failed( 756 yyParser *yypParser /* The parser */ 757 ){ 758 ssiexprparserARG_FETCH; 759 #ifndef NDEBUG 760 if( yyTraceFILE ){ 761 fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); 762 } 763 #endif 764 while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); 765 /* Here code is inserted which will be executed whenever the 766 ** parser fails */ 767 #line 14 "./mod_ssi_exprparser.y" 768 769 ctx->ok = 0; 770 771 #line 771 "mod_ssi_exprparser.c" 772 ssiexprparserARG_STORE; /* Suppress warning about unused %extra_argument variable */ 773 } 774 775 /* 776 ** The following code executes when a syntax error first occurs. 777 */ 778 static void yy_syntax_error( 779 yyParser *yypParser, /* The parser */ 780 int yymajor, /* The major type of the error token */ 781 YYMINORTYPE yyminor /* The minor type of the error token */ 782 ){ 783 ssiexprparserARG_FETCH; 784 UNUSED(yymajor); 785 UNUSED(yyminor); 786 #define TOKEN (yyminor.yy0) 787 ssiexprparserARG_STORE; /* Suppress warning about unused %extra_argument variable */ 788 } 789 790 /* 791 ** The following is executed when the parser accepts 792 */ 793 static void yy_accept( 794 yyParser *yypParser /* The parser */ 795 ){ 796 ssiexprparserARG_FETCH; 797 #ifndef NDEBUG 798 if( yyTraceFILE ){ 799 fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); 800 } 801 #endif 802 while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); 803 /* Here code is inserted which will be executed whenever the 804 ** parser accepts */ 805 ssiexprparserARG_STORE; /* Suppress warning about unused %extra_argument variable */ 806 } 807 808 /* The main parser program. 809 ** The first argument is a pointer to a structure obtained from 810 ** "ssiexprparserAlloc" which describes the current state of the parser. 811 ** The second argument is the major token number. The third is 812 ** the minor token. The fourth optional argument is whatever the 813 ** user wants (and specified in the grammar) and is available for 814 ** use by the action routines. 815 ** 816 ** Inputs: 817 ** <ul> 818 ** <li> A pointer to the parser (an opaque structure.) 819 ** <li> The major token number. 820 ** <li> The minor token number. 821 ** <li> An option argument of a grammar-specified type. 822 ** </ul> 823 ** 824 ** Outputs: 825 ** None. 826 */ 827 void ssiexprparser( 828 void *yyp, /* The parser */ 829 int yymajor, /* The major token code number */ 830 ssiexprparserTOKENTYPE yyminor /* The value for the token */ 831 ssiexprparserARG_PDECL /* Optional %extra_argument parameter */ 832 ){ 833 YYMINORTYPE yyminorunion; 834 int yyact; /* The parser action. */ 835 int yyendofinput; /* True if we are at the end of input */ 836 int yyerrorhit = 0; /* True if yymajor has invoked an error */ 837 yyParser *yypParser; /* The parser */ 838 839 /* (re)initialize the parser, if necessary */ 840 yypParser = (yyParser*)yyp; 841 if( yypParser->yyidx<0 ){ 842 if( yymajor==0 ) return; 843 yypParser->yyidx = 0; 844 yypParser->yyerrcnt = -1; 845 yypParser->yystack[0].stateno = 0; 846 yypParser->yystack[0].major = 0; 847 } 848 yyminorunion.yy0 = yyminor; 849 yyendofinput = (yymajor==0); 850 ssiexprparserARG_STORE; 851 852 #ifndef NDEBUG 853 if( yyTraceFILE ){ 854 fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); 855 } 856 #endif 857 858 do{ 859 yyact = yy_find_shift_action(yypParser,yymajor); 860 if( yyact<YYNSTATE ){ 861 yy_shift(yypParser,yyact,yymajor,&yyminorunion); 862 yypParser->yyerrcnt--; 863 if( yyendofinput && yypParser->yyidx>=0 ){ 864 yymajor = 0; 865 }else{ 866 yymajor = YYNOCODE; 867 } 868 }else if( yyact < YYNSTATE + YYNRULE ){ 869 yy_reduce(yypParser,yyact-YYNSTATE); 870 }else if( yyact == YY_ERROR_ACTION ){ 871 int yymx; 872 #ifndef NDEBUG 873 if( yyTraceFILE ){ 874 fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); 875 } 876 #endif 877 #ifdef YYERRORSYMBOL 878 /* A syntax error has occurred. 879 ** The response to an error depends upon whether or not the 880 ** grammar defines an error token "ERROR". 881 ** 882 ** This is what we do if the grammar does define ERROR: 883 ** 884 ** * Call the %syntax_error function. 885 ** 886 ** * Begin popping the stack until we enter a state where 887 ** it is legal to shift the error symbol, then shift 888 ** the error symbol. 889 ** 890 ** * Set the error count to three. 891 ** 892 ** * Begin accepting and shifting new tokens. No new error 893 ** processing will occur until three tokens have been 894 ** shifted successfully. 895 ** 896 */ 897 if( yypParser->yyerrcnt<0 ){ 898 yy_syntax_error(yypParser,yymajor,yyminorunion); 899 } 900 yymx = yypParser->yystack[yypParser->yyidx].major; 901 if( yymx==YYERRORSYMBOL || yyerrorhit ){ 902 #ifndef NDEBUG 903 if( yyTraceFILE ){ 904 fprintf(yyTraceFILE,"%sDiscard input token %s\n", 905 yyTracePrompt,yyTokenName[yymajor]); 906 } 907 #endif 908 yy_destructor(yymajor,&yyminorunion); 909 yymajor = YYNOCODE; 910 }else{ 911 while( 912 yypParser->yyidx >= 0 && 913 yymx != YYERRORSYMBOL && 914 (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE 915 ){ 916 yy_pop_parser_stack(yypParser); 917 } 918 if( yypParser->yyidx < 0 || yymajor==0 ){ 919 yy_destructor(yymajor,&yyminorunion); 920 yy_parse_failed(yypParser); 921 yymajor = YYNOCODE; 922 }else if( yymx!=YYERRORSYMBOL ){ 923 YYMINORTYPE u2; 924 u2.YYERRSYMDT = 0; 925 yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); 926 } 927 } 928 yypParser->yyerrcnt = 3; 929 yyerrorhit = 1; 930 #else /* YYERRORSYMBOL is not defined */ 931 /* This is what we do if the grammar does not define ERROR: 932 ** 933 ** * Report an error message, and throw away the input token. 934 ** 935 ** * If the input token is $, then fail the parse. 936 ** 937 ** As before, subsequent error messages are suppressed until 938 ** three input tokens have been successfully shifted. 939 */ 940 if( yypParser->yyerrcnt<=0 ){ 941 yy_syntax_error(yypParser,yymajor,yyminorunion); 942 } 943 yypParser->yyerrcnt = 3; 944 yy_destructor(yymajor,&yyminorunion); 945 if( yyendofinput ){ 946 yy_parse_failed(yypParser); 947 } 948 yymajor = YYNOCODE; 949 #endif 950 }else{ 951 yy_accept(yypParser); 952 yymajor = YYNOCODE; 953 } 954 }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); 955 return; 956 } 957