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