1*76404edcSAsim Jamshed %token_prefix TK_
2*76404edcSAsim Jamshed %token_type {buffer *}
3*76404edcSAsim Jamshed %extra_argument {ssi_ctx_t *ctx}
4*76404edcSAsim Jamshed %name ssiexprparser
5*76404edcSAsim Jamshed 
6*76404edcSAsim Jamshed %include {
7*76404edcSAsim Jamshed #include "mod_ssi_expr.h"
8*76404edcSAsim Jamshed #include "buffer.h"
9*76404edcSAsim Jamshed 
10*76404edcSAsim Jamshed #include <assert.h>
11*76404edcSAsim Jamshed #include <string.h>
12*76404edcSAsim Jamshed }
13*76404edcSAsim Jamshed 
14*76404edcSAsim Jamshed %parse_failure {
15*76404edcSAsim Jamshed   ctx->ok = 0;
16*76404edcSAsim Jamshed }
17*76404edcSAsim Jamshed 
18*76404edcSAsim Jamshed %type expr { ssi_val_t * }
19*76404edcSAsim Jamshed %type value { buffer * }
20*76404edcSAsim Jamshed %type exprline { ssi_val_t * }
21*76404edcSAsim Jamshed %type cond { int }
22*76404edcSAsim Jamshed %token_destructor { buffer_free($$); }
23*76404edcSAsim Jamshed 
24*76404edcSAsim Jamshed %left AND.
25*76404edcSAsim Jamshed %left OR.
26*76404edcSAsim Jamshed %nonassoc EQ NE GT GE LT LE.
27*76404edcSAsim Jamshed %right NOT.
28*76404edcSAsim Jamshed 
29*76404edcSAsim Jamshed input ::= exprline(B). {
30*76404edcSAsim Jamshed   ctx->val.bo = ssi_val_tobool(B);
31*76404edcSAsim Jamshed   ctx->val.type = SSI_TYPE_BOOL;
32*76404edcSAsim Jamshed 
33*76404edcSAsim Jamshed   ssi_val_free(B);
34*76404edcSAsim Jamshed }
35*76404edcSAsim Jamshed 
exprline(A)36*76404edcSAsim Jamshed exprline(A) ::= expr(B) cond(C) expr(D). {
37*76404edcSAsim Jamshed   int cmp;
38*76404edcSAsim Jamshed 
39*76404edcSAsim Jamshed   if (B->type == SSI_TYPE_STRING &&
40*76404edcSAsim Jamshed       D->type == SSI_TYPE_STRING) {
41*76404edcSAsim Jamshed        cmp = strcmp(B->str->ptr, D->str->ptr);
42*76404edcSAsim Jamshed   } else {
43*76404edcSAsim Jamshed     cmp = ssi_val_tobool(B) - ssi_val_tobool(D);
44*76404edcSAsim Jamshed   }
45*76404edcSAsim Jamshed 
46*76404edcSAsim Jamshed   A = B;
47*76404edcSAsim Jamshed 
48*76404edcSAsim Jamshed   switch(C) {
49*76404edcSAsim Jamshed   case SSI_COND_EQ: A->bo = (cmp == 0) ? 1 : 0; break;
50*76404edcSAsim Jamshed   case SSI_COND_NE: A->bo = (cmp != 0) ? 1 : 0; break;
51*76404edcSAsim Jamshed   case SSI_COND_GE: A->bo = (cmp >= 0) ? 1 : 0; break;
52*76404edcSAsim Jamshed   case SSI_COND_GT: A->bo = (cmp > 0) ? 1 : 0; break;
53*76404edcSAsim Jamshed   case SSI_COND_LE: A->bo = (cmp <= 0) ? 1 : 0; break;
54*76404edcSAsim Jamshed   case SSI_COND_LT: A->bo = (cmp < 0) ? 1 : 0; break;
55*76404edcSAsim Jamshed   }
56*76404edcSAsim Jamshed 
57*76404edcSAsim Jamshed   A->type = SSI_TYPE_BOOL;
58*76404edcSAsim Jamshed 
59*76404edcSAsim Jamshed   ssi_val_free(D);
60*76404edcSAsim Jamshed }
exprline(A)61*76404edcSAsim Jamshed exprline(A) ::= expr(B). {
62*76404edcSAsim Jamshed   A = B;
63*76404edcSAsim Jamshed }
expr(A)64*76404edcSAsim Jamshed expr(A) ::= expr(B) AND expr(C). {
65*76404edcSAsim Jamshed   int e;
66*76404edcSAsim Jamshed 
67*76404edcSAsim Jamshed   e = ssi_val_tobool(B) && ssi_val_tobool(C);
68*76404edcSAsim Jamshed 
69*76404edcSAsim Jamshed   A = B;
70*76404edcSAsim Jamshed   A->bo = e;
71*76404edcSAsim Jamshed   A->type = SSI_TYPE_BOOL;
72*76404edcSAsim Jamshed   ssi_val_free(C);
73*76404edcSAsim Jamshed }
74*76404edcSAsim Jamshed 
expr(A)75*76404edcSAsim Jamshed expr(A) ::= expr(B) OR expr(C). {
76*76404edcSAsim Jamshed   int e;
77*76404edcSAsim Jamshed 
78*76404edcSAsim Jamshed   e = ssi_val_tobool(B) || ssi_val_tobool(C);
79*76404edcSAsim Jamshed 
80*76404edcSAsim Jamshed   A = B;
81*76404edcSAsim Jamshed   A->bo = e;
82*76404edcSAsim Jamshed   A->type = SSI_TYPE_BOOL;
83*76404edcSAsim Jamshed   ssi_val_free(C);
84*76404edcSAsim Jamshed }
85*76404edcSAsim Jamshed 
expr(A)86*76404edcSAsim Jamshed expr(A) ::= NOT expr(B). {
87*76404edcSAsim Jamshed   int e;
88*76404edcSAsim Jamshed 
89*76404edcSAsim Jamshed   e = !ssi_val_tobool(B);
90*76404edcSAsim Jamshed 
91*76404edcSAsim Jamshed   A = B;
92*76404edcSAsim Jamshed   A->bo = e;
93*76404edcSAsim Jamshed   A->type = SSI_TYPE_BOOL;
94*76404edcSAsim Jamshed }
expr(A)95*76404edcSAsim Jamshed expr(A) ::= LPARAN exprline(B) RPARAN. {
96*76404edcSAsim Jamshed   A = B;
97*76404edcSAsim Jamshed }
98*76404edcSAsim Jamshed 
expr(A)99*76404edcSAsim Jamshed expr(A) ::= value(B). {
100*76404edcSAsim Jamshed   A = ssi_val_init();
101*76404edcSAsim Jamshed   A->str = B;
102*76404edcSAsim Jamshed   A->type = SSI_TYPE_STRING;
103*76404edcSAsim Jamshed }
104*76404edcSAsim Jamshed 
value(A)105*76404edcSAsim Jamshed value(A) ::= VALUE(B). {
106*76404edcSAsim Jamshed   A = B;
107*76404edcSAsim Jamshed }
108*76404edcSAsim Jamshed 
value(A)109*76404edcSAsim Jamshed value(A) ::= value(B) VALUE(C). {
110*76404edcSAsim Jamshed   A = B;
111*76404edcSAsim Jamshed   buffer_append_string_buffer(A, C);
112*76404edcSAsim Jamshed   buffer_free(C);
113*76404edcSAsim Jamshed }
114*76404edcSAsim Jamshed 
cond(A)115*76404edcSAsim Jamshed cond(A) ::= EQ. { A = SSI_COND_EQ; }
cond(A)116*76404edcSAsim Jamshed cond(A) ::= NE. { A = SSI_COND_NE; }
cond(A)117*76404edcSAsim Jamshed cond(A) ::= LE. { A = SSI_COND_LE; }
cond(A)118*76404edcSAsim Jamshed cond(A) ::= GE. { A = SSI_COND_GE; }
cond(A)119*76404edcSAsim Jamshed cond(A) ::= LT. { A = SSI_COND_LT; }
cond(A)120*76404edcSAsim Jamshed cond(A) ::= GT. { A = SSI_COND_GT; }
121