| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- /**
- * @file BPredicate.y
- * @author Ambroz Bizjak <ambrop7@gmail.com>
- *
- * @section LICENSE
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @section DESCRIPTION
- *
- * {@link BPredicate} grammar file.
- */
- %{
- #include <stdlib.h>
- #include <predicate/BPredicate_internal.h>
- #include <predicate/BPredicate_parser.h>
- #define YYLEX_PARAM scanner
- static struct predicate_node * make_constant (int val)
- {
- struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n));
- if (!n) {
- return NULL;
- }
- n->type = NODE_CONSTANT;
- n->constant.val = val;
- return n;
- }
- static struct predicate_node * make_negation (struct predicate_node *op)
- {
- if (!op) {
- goto fail;
- }
- struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n));
- if (!n) {
- goto fail;
- }
- n->type = NODE_NEG;
- n->neg.op = op;
- return n;
- fail:
- if (op) {
- free_predicate_node(op);
- }
- return NULL;
- }
- static struct predicate_node * make_conjunction (struct predicate_node *op1, struct predicate_node *op2)
- {
- if (!op1 || !op2) {
- goto fail;
- }
- struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n));
- if (!n) {
- goto fail;
- }
- n->type = NODE_CONJUNCT;
- n->conjunct.op1 = op1;
- n->conjunct.op2 = op2;
- return n;
- fail:
- if (op1) {
- free_predicate_node(op1);
- }
- if (op2) {
- free_predicate_node(op2);
- }
- return NULL;
- }
- static struct predicate_node * make_disjunction (struct predicate_node *op1, struct predicate_node *op2)
- {
- if (!op1 || !op2) {
- goto fail;
- }
- struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n));
- if (!n) {
- goto fail;
- }
- n->type = NODE_DISJUNCT;
- n->disjunct.op1 = op1;
- n->disjunct.op2 = op2;
- return n;
- fail:
- if (op1) {
- free_predicate_node(op1);
- }
- if (op2) {
- free_predicate_node(op2);
- }
- return NULL;
- }
- static struct predicate_node * make_function (char *name, struct arguments_node *args, int need_args)
- {
- if (!name || (!args && need_args)) {
- goto fail;
- }
- struct predicate_node *n = (struct predicate_node *)malloc(sizeof(*n));
- if (!n) {
- goto fail;
- }
- n->type = NODE_FUNCTION;
- n->function.name = name;
- n->function.args = args;
- return n;
- fail:
- if (name) {
- free(name);
- }
- if (args) {
- free_arguments_node(args);
- }
- return NULL;
- }
- static struct arguments_node * make_arguments (struct arguments_arg arg, struct arguments_node *next, int need_next)
- {
- if (arg.type == ARGUMENT_INVALID || (!next && need_next)) {
- goto fail;
- }
- struct arguments_node *n = (struct arguments_node *)malloc(sizeof(*n));
- if (!n) {
- goto fail;
- }
- n->arg = arg;
- n->next = next;
- return n;
- fail:
- free_argument(arg);
- if (next) {
- free_arguments_node(next);
- }
- return NULL;
- }
- static struct arguments_arg make_argument_predicate (struct predicate_node *pr)
- {
- struct arguments_arg ret;
- if (!pr) {
- goto fail;
- }
- ret.type = ARGUMENT_PREDICATE;
- ret.predicate = pr;
- return ret;
- fail:
- ret.type = ARGUMENT_INVALID;
- return ret;
- }
- static struct arguments_arg make_argument_string (char *string)
- {
- struct arguments_arg ret;
- if (!string) {
- goto fail;
- }
- ret.type = ARGUMENT_STRING;
- ret.string = string;
- return ret;
- fail:
- ret.type = ARGUMENT_INVALID;
- return ret;
- }
- %}
- %pure-parser
- %locations
- %parse-param {void *scanner}
- %parse-param {struct predicate_node **result}
- %union {
- char *text;
- struct predicate_node *node;
- struct arguments_node *arg_node;
- struct predicate_node nfaw;
- struct arguments_arg arg_arg;
- };
- // token types
- %token <text> STRING NAME
- %token PEER1_NAME PEER2_NAME AND OR NOT SPAR EPAR CONSTANT_TRUE CONSTANT_FALSE COMMA
- // string token destructor
- %destructor {
- free($$);
- } STRING NAME
- // return values
- %type <node> predicate constant parentheses neg conjunct disjunct function
- %type <arg_node> arguments
- %type <arg_arg> argument
- // predicate node destructor
- %destructor {
- if ($$) {
- free_predicate_node($$);
- }
- } predicate constant parentheses neg conjunct disjunct function
- // argument node destructor
- %destructor {
- if ($$) {
- free_arguments_node($$);
- }
- } arguments
- // argument argument destructor
- %destructor {
- free_argument($$);
- } argument
- %left OR
- %left AND
- %nonassoc NOT
- %right COMMA
- %%
- input:
- predicate {
- *result = $1;
- }
- ;
- predicate: constant | parentheses | neg | conjunct | disjunct | function;
- constant:
- CONSTANT_TRUE {
- $$ = make_constant(1);
- }
- |
- CONSTANT_FALSE {
- $$ = make_constant(0);
- }
- ;
- parentheses:
- SPAR predicate EPAR {
- $$ = $2;
- }
- ;
- neg:
- NOT predicate {
- $$ = make_negation($2);
- }
- ;
- conjunct:
- predicate AND predicate {
- $$ = make_conjunction($1, $3);
- }
- ;
- disjunct:
- predicate OR predicate {
- $$ = make_disjunction($1, $3);
- }
- ;
- function:
- NAME SPAR EPAR {
- $$ = make_function($1, NULL, 0);
- }
- |
- NAME SPAR arguments EPAR {
- $$ = make_function($1, $3, 1);
- }
- ;
- arguments:
- argument {
- $$ = make_arguments($1, NULL, 0);
- }
- |
- argument COMMA arguments {
- $$ = make_arguments($1, $3, 1);
- }
- ;
- argument:
- predicate {
- $$ = make_argument_predicate($1);
- }
- |
- STRING {
- $$ = make_argument_string($1);
- }
- ;
|