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)36exprline(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)61exprline(A) ::= expr(B). { 62 A = B; 63 } expr(A)64expr(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)75expr(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)86expr(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)95expr(A) ::= LPARAN exprline(B) RPARAN. { 96 A = B; 97 } 98 expr(A)99expr(A) ::= value(B). { 100 A = ssi_val_init(); 101 A->str = B; 102 A->type = SSI_TYPE_STRING; 103 } 104 value(A)105value(A) ::= VALUE(B). { 106 A = B; 107 } 108 value(A)109value(A) ::= value(B) VALUE(C). { 110 A = B; 111 buffer_append_string_buffer(A, C); 112 buffer_free(C); 113 } 114 cond(A)115cond(A) ::= EQ. { A = SSI_COND_EQ; } cond(A)116cond(A) ::= NE. { A = SSI_COND_NE; } cond(A)117cond(A) ::= LE. { A = SSI_COND_LE; } cond(A)118cond(A) ::= GE. { A = SSI_COND_GE; } cond(A)119cond(A) ::= LT. { A = SSI_COND_LT; } cond(A)120cond(A) ::= GT. { A = SSI_COND_GT; } 121