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 */
ssiexprparserAlloc(void * (* mallocProc)(size_t))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 */
yy_destructor(YYCODETYPE yymajor,YYMINORTYPE * yypminor)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 */
yy_pop_parser_stack(yyParser * pParser)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 */
ssiexprparserFree(void * p,void (* freeProc)(void *))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 */
yy_find_shift_action(yyParser * pParser,int iLookAhead)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 */
yy_find_reduce_action(yyParser * pParser,int iLookAhead)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 */
yy_shift(yyParser * yypParser,int yyNewState,int yyMajor,YYMINORTYPE * yypMinor)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 */
yy_reduce(yyParser * yypParser,int yyruleno)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 */
yy_parse_failed(yyParser * yypParser)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 */
yy_syntax_error(yyParser * yypParser,int yymajor,YYMINORTYPE yyminor)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 */
yy_accept(yyParser * yypParser)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 */
ssiexprparser(void * yyp,int yymajor,ssiexprparserTOKENTYPE yyminor ssiexprparserARG_PDECL)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