0001 /**
0002 * @brief UBF Expression Evaluator.
0003 *
0004 * @file expr.y
0005 */
0006 /* -----------------------------------------------------------------------------
0007 * Enduro/X Middleware Platform for Distributed Transaction Processing
0008 * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009 * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010 * This software is released under one of the following licenses:
0011 * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012 * See LICENSE file for full text.
0013 * -----------------------------------------------------------------------------
0014 * AGPL license:
0015 *
0016 * This program is free software; you can redistribute it and/or modify it under
0017 * the terms of the GNU Affero General Public License, version 3 as published
0018 * by the Free Software Foundation;
0019 *
0020 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022 * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023 * for more details.
0024 *
0025 * You should have received a copy of the GNU Affero General Public License along
0026 * with this program; if not, write to the Free Software Foundation, Inc.,
0027 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028 *
0029 * -----------------------------------------------------------------------------
0030 * A commercial use license is available from Mavimax, Ltd
0031 * contact@mavimax.com
0032 * -----------------------------------------------------------------------------
0033 */
0034
0035 %{
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include "ndebug.h"
0039 #include <ubf_int.h>
0040 #include "expr.h"
0041
0042 extern int yylex (void);
0043 %}
0044
0045 %union {
0046 struct ast *a;
0047 double d;
0048 long l;
0049 struct symbol *s; /* which symbol */
0050 struct symlist *sl;
0051 int fn; /* which function */
0052 ndrx_ubf_rfldid_t fld;
0053 char strval[MAX_TEXT+1]; /* String value */
0054 ndrx_symbfunc_t *funccall; /* Function name */
0055 }
0056
0057 %locations
0058
0059 /* declare tokens */
0060 %token EOL
0061 %token OR
0062 %token AND
0063 %token XOR
0064 %token <fn> EQOP
0065 %token <fn> EQOP_REG
0066 %token <fn> RELOP
0067 %token <fn> ADDOP
0068 %token <fn> MULTOP
0069 %token <fn> UNARYOP
0070 %token <d> UFLOAT
0071 %token <l> ULONG
0072 %token <strval> STRING
0073 %token <fld> FLDREF
0074 %token <funccall> FUNCREF
0075 %token META
0076 %token OP
0077 %token CP
0078
0079 %type <a> boolean logical_and xor_expr equality_expr
0080 relational_expr additive_expr multiplicative_expr
0081 unary_expr primary_expr
0082 unsigned_constant unsigned_number string_constant field_ref func_ref
0083
0084 %start calclist
0085
0086 %%
0087 /**
0088 * $1 - left arg
0089 * $2 - operation in the middle.
0090 * $3 - right arg
0091 * Like:
0092 * 4!=5 will be: $1->4, $2->value populated, $3->
0093 */
0094 /*
0095 * Note that %% and !% works only for string vs string or field vs string.
0096 */
0097 boolean: logical_and
0098 | boolean OR logical_and {$$ = newast(NODE_TYPE_OR, SUB_OR_OP, $1, $3); if (!$$ || G_error) YYERROR; }
0099 ;
0100 logical_and: xor_expr
0101 | logical_and AND xor_expr {$$ = newast(NODE_TYPE_AND, SUB_AND_OP, $1, $3); if (!$$ || G_error) YYERROR; }
0102 ;
0103 xor_expr: equality_expr
0104 | xor_expr XOR equality_expr {$$ = newast(NODE_TYPE_XOR, SUB_XOR_OP, $1, $3); if (!$$ || G_error) YYERROR; }
0105 ;
0106 equality_expr: relational_expr
0107 | string_constant EQOP_REG string_constant {$$ = newast(NODE_TYPE_EQOP, $2, $1, $3); if (!$$ || G_error) YYERROR; }
0108 | field_ref EQOP_REG string_constant {$$ = newast(NODE_TYPE_EQOP, $2, $1, $3); if (!$$ || G_error) YYERROR; }
0109 | equality_expr EQOP relational_expr {$$ = newast(NODE_TYPE_EQOP, $2, $1, $3); if (!$$ || G_error) YYERROR; }
0110 ;
0111 relational_expr: additive_expr
0112 | relational_expr RELOP additive_expr {$$ = newast(NODE_TYPE_RELOP, $2, $1, $3); if (!$$ || G_error) YYERROR; }
0113 ;
0114 additive_expr: multiplicative_expr
0115 | additive_expr ADDOP multiplicative_expr {$$ = newast(NODE_TYPE_ADDOP, $2, $1, $3); if (!$$ || G_error) YYERROR; }
0116 ;
0117 multiplicative_expr: unary_expr
0118 | multiplicative_expr MULTOP unary_expr {$$ = newast(NODE_TYPE_MULTOP, $2, $1, $3); if (!$$ || G_error) YYERROR; }
0119 ;
0120 unary_expr: primary_expr
0121 | UNARYOP primary_expr {$$ = newast(NODE_TYPE_UNARY, $1, NULL, $2); if (!$$ || G_error) YYERROR; }
0122 | ADDOP primary_expr {$$ = newast(NODE_TYPE_UNARY, $1, NULL, $2); if (!$$ || G_error) YYERROR; }
0123 ;
0124 primary_expr: unsigned_constant
0125 | OP boolean CP {$$ = $2;}
0126 | field_ref
0127 | func_ref
0128 ;
0129 unsigned_constant: unsigned_number
0130 | string_constant
0131 ;
0132 unsigned_number: UFLOAT {$$ = newfloat($1); if (!$$ || G_error) YYERROR; }
0133 | ULONG {$$ = newlong($1); if (!$$ || G_error) YYERROR; }
0134 ;
0135 string_constant: STRING {$$ = newstring($1); if (!$$ || G_error) YYERROR; }
0136 ;
0137 field_ref: FLDREF {$$ = newfld($1); if (!$$ || G_error) YYERROR; }
0138 ;
0139 func_ref: FUNCREF {$$ = newfunc($1); if (!$$ || G_error) YYERROR; }
0140 ;
0141
0142 calclist: /* nothing */
0143 | calclist boolean EOL {
0144 G_p_root_node = $2;
0145 }
0146 ;
0147 %%
0148
0149
0150 /* vim: set ts=4 sw=4 et smartindent: */