2001-02-01 20:21:25 +00:00
|
|
|
|
|
|
|
%include {
|
|
|
|
#include "config.h"
|
|
|
|
|
2013-11-10 15:59:37 +00:00
|
|
|
#include <assert.h>
|
|
|
|
|
2001-02-01 20:21:25 +00:00
|
|
|
#include "dfilter-int.h"
|
|
|
|
#include "syntax-tree.h"
|
2022-06-23 23:07:42 +00:00
|
|
|
#include "sttype-field.h"
|
|
|
|
#include "sttype-slice.h"
|
2022-06-27 05:37:45 +00:00
|
|
|
#include "sttype-op.h"
|
2006-05-02 14:26:17 +00:00
|
|
|
#include "sttype-function.h"
|
2015-08-19 03:03:41 +00:00
|
|
|
#include "sttype-set.h"
|
2001-02-27 19:23:30 +00:00
|
|
|
#include "drange.h"
|
2001-02-01 20:21:25 +00:00
|
|
|
|
2005-08-20 16:19:22 +00:00
|
|
|
#include "grammar.h"
|
|
|
|
|
2007-04-03 19:08:00 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#pragma warning(disable:4671)
|
|
|
|
#endif
|
2015-08-26 08:32:52 +00:00
|
|
|
|
2021-11-05 06:41:41 +00:00
|
|
|
static stnode_t *
|
2022-04-07 23:12:56 +00:00
|
|
|
new_function(dfwork_t *dfw, stnode_t *node);
|
2022-04-04 11:52:41 +00:00
|
|
|
|
2022-11-19 19:21:19 +00:00
|
|
|
#define FAIL(dfw, node, ...) dfilter_fail(dfw, DF_ERROR_GENERIC, stnode_location(node), __VA_ARGS__)
|
2022-04-07 12:57:39 +00:00
|
|
|
|
2022-11-19 22:52:09 +00:00
|
|
|
DIAG_OFF_LEMON()
|
|
|
|
} /* end of %include */
|
|
|
|
|
|
|
|
%code {
|
|
|
|
DIAG_ON_LEMON()
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Parser Information */
|
2021-12-01 19:45:30 +00:00
|
|
|
%name Dfilter
|
|
|
|
%token_prefix TOKEN_
|
|
|
|
%extra_argument {dfwork_t *dfw}
|
2001-02-01 20:21:25 +00:00
|
|
|
|
|
|
|
/* Terminal and Non-Terminal types and destructors */
|
2022-04-07 23:12:56 +00:00
|
|
|
%token_type {stnode_t*}
|
2021-12-01 19:45:30 +00:00
|
|
|
%token_destructor {
|
|
|
|
(void)dfw;
|
2022-04-07 23:12:56 +00:00
|
|
|
stnode_free($$);
|
2013-12-14 23:44:25 +00:00
|
|
|
}
|
2001-02-01 20:21:25 +00:00
|
|
|
|
2021-12-01 19:45:30 +00:00
|
|
|
%default_type {stnode_t*}
|
|
|
|
%default_destructor {stnode_free($$);}
|
2001-02-01 20:21:25 +00:00
|
|
|
|
2021-12-01 19:45:30 +00:00
|
|
|
%type range_node_list {GSList*}
|
|
|
|
%destructor range_node_list {drange_node_free_list($$);}
|
2001-02-27 19:23:30 +00:00
|
|
|
|
2022-06-23 23:07:42 +00:00
|
|
|
%type layer {GSList*}
|
|
|
|
%destructor layer {drange_node_free_list($$);}
|
|
|
|
|
2021-12-01 19:45:30 +00:00
|
|
|
%type function_params {GSList*}
|
|
|
|
%destructor function_params {st_funcparams_free($$);}
|
2006-05-02 14:26:17 +00:00
|
|
|
|
2021-12-01 19:45:30 +00:00
|
|
|
%type set_list {GSList*}
|
|
|
|
%destructor set_list {set_nodelist_free($$);}
|
2021-10-26 09:35:12 +00:00
|
|
|
|
2021-12-01 19:45:30 +00:00
|
|
|
%type set_element {GSList*}
|
|
|
|
%destructor set_element {set_nodelist_free($$);}
|
2015-08-19 03:03:41 +00:00
|
|
|
|
2001-02-01 20:21:25 +00:00
|
|
|
/* This is called as soon as a syntax error happens. After that,
|
|
|
|
any "error" symbols are shifted, if possible. */
|
|
|
|
%syntax_error {
|
2021-12-01 19:45:30 +00:00
|
|
|
if (!TOKEN) {
|
2022-11-19 11:14:57 +00:00
|
|
|
dfilter_fail(dfw, DF_ERROR_UNEXPECTED_END, NULL, "Unexpected end of filter expression.");
|
2021-12-01 19:45:30 +00:00
|
|
|
return;
|
|
|
|
}
|
2022-04-07 12:57:39 +00:00
|
|
|
FAIL(dfw, TOKEN, "\"%s\" was unexpected in this context.", stnode_token(TOKEN));
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* When a parse fails, mark an error. This occurs after
|
|
|
|
the above syntax_error code and after the parser fails to
|
|
|
|
use error recovery, shifting an "error" symbol and successfully
|
|
|
|
shifting 3 more symbols. */
|
|
|
|
%parse_failure {
|
2022-11-19 19:21:19 +00:00
|
|
|
dfw->parse_failure = TRUE;
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------- The grammar -------------- */
|
|
|
|
|
|
|
|
/* Associativity */
|
|
|
|
%left TEST_OR.
|
2022-04-03 16:57:23 +00:00
|
|
|
%left TEST_AND.
|
|
|
|
%right TEST_NOT.
|
2021-12-13 01:06:01 +00:00
|
|
|
%nonassoc TEST_ALL_EQ TEST_ANY_EQ TEST_ALL_NE TEST_ANY_NE TEST_LT TEST_LE TEST_GT TEST_GE
|
2022-04-04 11:52:41 +00:00
|
|
|
TEST_CONTAINS TEST_MATCHES.
|
|
|
|
%left BITWISE_AND.
|
|
|
|
%left PLUS MINUS.
|
|
|
|
%left STAR RSLASH PERCENT.
|
2022-04-04 15:52:11 +00:00
|
|
|
%nonassoc UNARY_PLUS UNARY_MINUS.
|
2001-02-01 20:21:25 +00:00
|
|
|
|
|
|
|
/* Top-level targets */
|
2021-12-01 19:45:30 +00:00
|
|
|
sentence ::= expr(X). { dfw->st_root = X; }
|
|
|
|
sentence ::= . { dfw->st_root = NULL; }
|
2001-02-01 20:21:25 +00:00
|
|
|
|
2022-04-19 23:04:05 +00:00
|
|
|
expr(X) ::= relation(R). { X = R; }
|
2022-04-04 15:52:11 +00:00
|
|
|
expr(X) ::= arithmetic_expr(E). { X = E; }
|
2001-02-01 20:21:25 +00:00
|
|
|
|
|
|
|
/* Logical tests */
|
2022-04-04 15:52:11 +00:00
|
|
|
expr(X) ::= expr(Y) TEST_AND(T) expr(Z).
|
2001-02-01 20:21:25 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
X = T;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(X, STNODE_OP_AND, Y, Z);
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
expr(X) ::= expr(Y) TEST_OR(T) expr(Z).
|
2001-02-01 20:21:25 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
X = T;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(X, STNODE_OP_OR, Y, Z);
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
expr(X) ::= TEST_NOT(T) expr(Y).
|
2001-02-01 20:21:25 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
X = T;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set1(X, STNODE_OP_NOT, Y);
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
/* Any expression inside parens is simply that expression */
|
2022-04-07 23:12:56 +00:00
|
|
|
expr(X) ::= LPAREN expr(Y) RPAREN. { X = Y; }
|
2001-02-01 20:21:25 +00:00
|
|
|
|
|
|
|
/* Entities, or things that can be compared/tested/checked */
|
2022-04-07 23:12:56 +00:00
|
|
|
atom(A) ::= STRING(S). { A = S; }
|
|
|
|
atom(A) ::= CHARCONST(N). { A = N; }
|
|
|
|
atom(A) ::= LITERAL(S). { A = S; }
|
2022-04-04 15:52:11 +00:00
|
|
|
|
2022-06-23 23:07:42 +00:00
|
|
|
layer(R) ::= HASH LBRACKET range_node_list(L) RBRACKET.
|
2022-04-09 22:03:40 +00:00
|
|
|
{
|
2022-06-23 23:07:42 +00:00
|
|
|
R = L;
|
2022-04-09 22:03:40 +00:00
|
|
|
}
|
|
|
|
|
2022-06-23 23:07:42 +00:00
|
|
|
layer(R) ::= HASH INTEGER(N).
|
2022-04-09 22:03:40 +00:00
|
|
|
{
|
2022-06-23 23:07:42 +00:00
|
|
|
char *err_msg = NULL;
|
|
|
|
drange_node *range = drange_node_from_str(stnode_token(N), &err_msg);
|
2022-04-09 22:03:40 +00:00
|
|
|
if (err_msg != NULL) {
|
|
|
|
FAIL(dfw, N, "%s", err_msg);
|
|
|
|
g_free(err_msg);
|
|
|
|
}
|
|
|
|
stnode_free(N);
|
2022-06-23 23:07:42 +00:00
|
|
|
R = g_slist_append(NULL, range);
|
|
|
|
}
|
|
|
|
|
2022-10-25 03:20:18 +00:00
|
|
|
layered_field(R) ::= FIELD(F).
|
2022-06-23 23:07:42 +00:00
|
|
|
{
|
|
|
|
R = F;
|
|
|
|
}
|
|
|
|
|
2022-10-25 03:20:18 +00:00
|
|
|
layered_field(R) ::= FIELD(F) layer(L).
|
2022-06-23 23:07:42 +00:00
|
|
|
{
|
|
|
|
R = F;
|
|
|
|
sttype_field_set_range(R, L);
|
|
|
|
g_slist_free(L);
|
|
|
|
}
|
|
|
|
|
2022-10-25 03:20:18 +00:00
|
|
|
layered_field(R) ::= UNPARSED(U) layer(L).
|
2022-06-23 23:07:42 +00:00
|
|
|
{
|
2022-06-25 10:25:36 +00:00
|
|
|
header_field_info *hfinfo = dfilter_resolve_unparsed(dfw, stnode_token(U));
|
2022-06-23 23:07:42 +00:00
|
|
|
if (hfinfo == NULL) {
|
|
|
|
FAIL(dfw, U, "%s is not a valid field", stnode_token(U));
|
|
|
|
}
|
|
|
|
R = stnode_new(STTYPE_FIELD, hfinfo, NULL, stnode_location(U));
|
|
|
|
stnode_free(U);
|
|
|
|
sttype_field_set_range(R, L);
|
|
|
|
g_slist_free(L);
|
|
|
|
}
|
|
|
|
|
2022-10-25 03:20:18 +00:00
|
|
|
field(R) ::= layered_field(F).
|
|
|
|
{
|
|
|
|
R = F;
|
|
|
|
}
|
|
|
|
|
|
|
|
field(R) ::= ATSIGN layered_field(F).
|
|
|
|
{
|
|
|
|
R = F;
|
|
|
|
sttype_field_set_raw(R, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
field(R) ::= ATSIGN UNPARSED(U).
|
|
|
|
{
|
|
|
|
const char *token = stnode_token(U);
|
|
|
|
const stloc_t *loc = stnode_location(U);
|
|
|
|
header_field_info *hfinfo = dfilter_resolve_unparsed(dfw, token);
|
|
|
|
if (hfinfo == NULL) {
|
|
|
|
FAIL(dfw, U, "%s is not a valid field", stnode_token(U));
|
|
|
|
}
|
|
|
|
R = stnode_new(STTYPE_FIELD, hfinfo, g_strdup(token), loc);
|
|
|
|
sttype_field_set_raw(R, TRUE);
|
|
|
|
stnode_free(U);
|
|
|
|
}
|
|
|
|
|
2022-06-23 23:07:42 +00:00
|
|
|
reference(R) ::= DOLLAR LBRACE field(F) RBRACE.
|
|
|
|
{
|
|
|
|
/* convert field to reference */
|
|
|
|
R = stnode_new(STTYPE_REFERENCE, sttype_field_hfinfo(F), NULL, stnode_location(F));
|
|
|
|
sttype_field_set_drange(R, sttype_field_drange_steal(F));
|
2022-10-25 12:03:08 +00:00
|
|
|
sttype_field_set_raw(R, sttype_field_raw(F));
|
2022-06-23 23:07:42 +00:00
|
|
|
stnode_free(F);
|
|
|
|
}
|
|
|
|
|
|
|
|
reference(R) ::= DOLLAR LBRACE UNPARSED(U) RBRACE.
|
|
|
|
{
|
2022-06-25 10:25:36 +00:00
|
|
|
header_field_info *hfinfo = dfilter_resolve_unparsed(dfw, stnode_token(U));
|
2022-06-23 23:07:42 +00:00
|
|
|
if (hfinfo == NULL) {
|
|
|
|
FAIL(dfw, U, "%s is not a valid field", stnode_token(U));
|
|
|
|
}
|
|
|
|
R = stnode_new(STTYPE_REFERENCE, hfinfo, NULL, stnode_location(U));
|
|
|
|
stnode_free(U);
|
2022-04-09 22:03:40 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
entity(E) ::= atom(A). { E = A; }
|
2022-04-11 19:06:49 +00:00
|
|
|
entity(E) ::= slice(R). { E = R; }
|
2021-12-01 19:45:30 +00:00
|
|
|
entity(E) ::= function(F). { E = F; }
|
2022-06-23 23:07:42 +00:00
|
|
|
entity(E) ::= field(F). { E = F; }
|
|
|
|
entity(E) ::= reference(R). { E = R; }
|
2022-06-25 10:25:36 +00:00
|
|
|
entity(E) ::= UNPARSED(U).
|
|
|
|
{
|
|
|
|
const char *token = stnode_token(U);
|
|
|
|
const stloc_t *loc = stnode_location(U);
|
|
|
|
header_field_info *hfinfo = dfilter_resolve_unparsed(dfw, token);
|
|
|
|
if (hfinfo != NULL) {
|
|
|
|
E = stnode_new(STTYPE_FIELD, hfinfo, g_strdup(token), loc);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
E = stnode_new(STTYPE_LITERAL, g_strdup(token), g_strdup(token), loc);
|
|
|
|
}
|
|
|
|
stnode_free(U);
|
|
|
|
}
|
2001-02-01 20:21:25 +00:00
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
arithmetic_expr(T) ::= entity(N).
|
|
|
|
{
|
|
|
|
T = N;
|
|
|
|
}
|
2022-02-25 19:37:53 +00:00
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
arithmetic_expr(T) ::= PLUS entity(N). [UNARY_PLUS]
|
2022-02-27 09:56:41 +00:00
|
|
|
{
|
|
|
|
T = N;
|
|
|
|
}
|
|
|
|
|
2022-04-07 23:12:56 +00:00
|
|
|
arithmetic_expr(T) ::= MINUS(M) entity(N). [UNARY_MINUS]
|
2022-02-27 09:56:41 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = M;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set1(T, STNODE_OP_UNARY_MINUS, N);
|
2022-02-27 09:56:41 +00:00
|
|
|
}
|
2022-02-25 19:37:53 +00:00
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
arithmetic_expr(T) ::= arithmetic_expr(F) BITWISE_AND(O) arithmetic_expr(M).
|
2022-03-31 13:50:20 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = O;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_BITWISE_AND, F, M);
|
2022-03-31 13:50:20 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
arithmetic_expr(T) ::= arithmetic_expr(F) PLUS(O) arithmetic_expr(M).
|
2001-02-01 20:21:25 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = O;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_ADD, F, M);
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
arithmetic_expr(T) ::= arithmetic_expr(F) MINUS(O) arithmetic_expr(M).
|
2001-02-01 20:21:25 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = O;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_SUBTRACT, F, M);
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
arithmetic_expr(T) ::= arithmetic_expr(F) STAR(O) arithmetic_expr(M).
|
2001-02-01 20:21:25 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = O;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_MULTIPLY, F, M);
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
arithmetic_expr(T) ::= arithmetic_expr(F) RSLASH(O) arithmetic_expr(M).
|
2001-02-01 20:21:25 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = O;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_DIVIDE, F, M);
|
2022-04-04 15:52:11 +00:00
|
|
|
}
|
2021-10-08 12:26:53 +00:00
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
arithmetic_expr(T) ::= arithmetic_expr(F) PERCENT(O) arithmetic_expr(M).
|
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = O;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_MODULO, F, M);
|
2022-04-04 15:52:11 +00:00
|
|
|
}
|
2001-02-27 19:23:30 +00:00
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
arithmetic_expr(T) ::= LBRACE arithmetic_expr(F) RBRACE.
|
|
|
|
{
|
|
|
|
T = F;
|
2001-02-27 19:23:30 +00:00
|
|
|
}
|
|
|
|
|
2001-02-01 20:21:25 +00:00
|
|
|
/* Relational tests */
|
2022-06-27 05:37:45 +00:00
|
|
|
cmp_op(O) ::= TEST_ALL_EQ(L). { O = L; sttype_oper_set_op(O, STNODE_OP_ALL_EQ); }
|
|
|
|
cmp_op(O) ::= TEST_ANY_EQ(L). { O = L; sttype_oper_set_op(O, STNODE_OP_ANY_EQ); }
|
|
|
|
cmp_op(O) ::= TEST_ALL_NE(L). { O = L; sttype_oper_set_op(O, STNODE_OP_ALL_NE); }
|
|
|
|
cmp_op(O) ::= TEST_ANY_NE(L). { O = L; sttype_oper_set_op(O, STNODE_OP_ANY_NE); }
|
|
|
|
cmp_op(O) ::= TEST_GT(L). { O = L; sttype_oper_set_op(O, STNODE_OP_GT); }
|
|
|
|
cmp_op(O) ::= TEST_GE(L). { O = L; sttype_oper_set_op(O, STNODE_OP_GE); }
|
|
|
|
cmp_op(O) ::= TEST_LT(L). { O = L; sttype_oper_set_op(O, STNODE_OP_LT); }
|
|
|
|
cmp_op(O) ::= TEST_LE(L). { O = L; sttype_oper_set_op(O, STNODE_OP_LE); }
|
2021-11-05 06:30:40 +00:00
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
comparison_test(T) ::= arithmetic_expr(E) cmp_op(O) arithmetic_expr(F).
|
2001-02-01 20:21:25 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
T = O;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2_args(O, E, F);
|
2001-02-01 20:21:25 +00:00
|
|
|
}
|
|
|
|
|
2012-06-19 12:12:41 +00:00
|
|
|
/* 'a == b == c' or 'a < b <= c <= d < e' */
|
2022-04-04 15:52:11 +00:00
|
|
|
comparison_test(T) ::= arithmetic_expr(E) cmp_op(O) comparison_test(R).
|
2012-06-19 12:12:41 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
stnode_t *L, *F;
|
2022-06-27 05:37:45 +00:00
|
|
|
/* for now generate it like E O F STNODE_OP_AND F P G, later it could be optimized
|
2021-12-01 19:45:30 +00:00
|
|
|
or semantically checked (to make a <= b >= c or a == b != c invalid)?
|
|
|
|
*/
|
2012-06-19 12:12:41 +00:00
|
|
|
|
2021-12-01 19:45:30 +00:00
|
|
|
F = R;
|
|
|
|
do {
|
|
|
|
ws_assert(F != NULL && stnode_type_id(F) == STTYPE_TEST);
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_get(F, NULL, &F, NULL);
|
2021-12-01 19:45:30 +00:00
|
|
|
} while (stnode_type_id(F) == STTYPE_TEST);
|
2012-06-19 12:12:41 +00:00
|
|
|
|
2021-12-01 19:45:30 +00:00
|
|
|
L = O;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2_args(L, E, stnode_dup(F));
|
2012-06-19 12:12:41 +00:00
|
|
|
|
2022-04-07 12:57:39 +00:00
|
|
|
T = stnode_new(STTYPE_TEST, NULL, NULL, NULL);
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_AND, L, R);
|
2012-06-19 12:12:41 +00:00
|
|
|
}
|
|
|
|
|
2021-12-01 19:45:30 +00:00
|
|
|
relation_test(T) ::= comparison_test(C). { T = C; }
|
2021-11-05 06:30:40 +00:00
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
relation_test(T) ::= entity(E) TEST_CONTAINS(L) entity(F).
|
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = L;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_CONTAINS, E, F);
|
2022-04-04 15:52:11 +00:00
|
|
|
}
|
2021-11-05 06:30:40 +00:00
|
|
|
|
2022-04-04 15:52:11 +00:00
|
|
|
relation_test(T) ::= entity(E) TEST_MATCHES(L) entity(F).
|
2021-10-14 16:21:10 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = L;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_MATCHES, E, F);
|
2021-10-14 16:21:10 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 01:10:11 +00:00
|
|
|
relation_test(T) ::= entity(E) TEST_IN(O) set(S).
|
2015-08-19 03:03:41 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = O;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(T, STNODE_OP_IN, E, S);
|
2015-08-19 03:03:41 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 01:10:11 +00:00
|
|
|
relation_test(T) ::= entity(E) TEST_NOT(P) TEST_IN(O) set(S).
|
2021-10-18 17:31:59 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
T = P;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set2(O, STNODE_OP_IN, E, S);
|
|
|
|
sttype_oper_set1(T, STNODE_OP_NOT, O);
|
2021-10-18 17:31:59 +00:00
|
|
|
}
|
2022-04-19 23:04:05 +00:00
|
|
|
|
|
|
|
relation(R) ::= relation_test(T). { R = T; }
|
|
|
|
|
|
|
|
relation(R) ::= ANY relation_test(T).
|
|
|
|
{
|
|
|
|
R = T;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_test_set_match(R, STNODE_MATCH_ANY);
|
2022-04-19 23:04:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
relation(R) ::= ALL relation_test(T).
|
|
|
|
{
|
|
|
|
R = T;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_test_set_match(R, STNODE_MATCH_ALL);
|
2022-04-19 23:04:05 +00:00
|
|
|
}
|
2021-10-18 17:31:59 +00:00
|
|
|
|
2021-10-26 09:35:12 +00:00
|
|
|
set(S) ::= LBRACE set_list(L) RBRACE.
|
|
|
|
{
|
2022-04-07 12:57:39 +00:00
|
|
|
S = stnode_new(STTYPE_SET, L, NULL, NULL);
|
2021-10-26 09:35:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
set_list(L) ::= set_element(N).
|
2015-08-19 03:03:41 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
L = g_slist_concat(NULL, N);
|
2015-08-19 03:03:41 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 17:20:38 +00:00
|
|
|
set_list(L) ::= set_list(P) COMMA set_element(N).
|
2015-08-19 03:03:41 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
L = g_slist_concat(P, N);
|
2018-04-14 16:07:22 +00:00
|
|
|
}
|
|
|
|
|
2022-06-25 10:25:36 +00:00
|
|
|
set_entity(N) ::= entity(E).
|
2022-02-27 09:56:41 +00:00
|
|
|
{
|
2022-06-25 10:25:36 +00:00
|
|
|
N = E;
|
2022-02-27 09:56:41 +00:00
|
|
|
}
|
|
|
|
|
2022-06-25 10:25:36 +00:00
|
|
|
set_entity(N) ::= MINUS(M) entity(E).
|
2022-02-27 09:56:41 +00:00
|
|
|
{
|
2022-04-07 23:12:56 +00:00
|
|
|
N = M;
|
2022-06-27 05:37:45 +00:00
|
|
|
sttype_oper_set1(N, STNODE_OP_UNARY_MINUS, E);
|
2022-02-27 09:56:41 +00:00
|
|
|
}
|
|
|
|
|
2022-06-25 10:25:36 +00:00
|
|
|
set_entity(N) ::= PLUS entity(E).
|
2022-02-27 09:56:41 +00:00
|
|
|
{
|
2022-06-25 10:25:36 +00:00
|
|
|
N = E;
|
2022-02-27 09:56:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
set_element(N) ::= set_entity(X).
|
2018-04-14 16:07:22 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
N = g_slist_append(NULL, X);
|
|
|
|
N = g_slist_append(N, NULL);
|
2018-04-14 16:07:22 +00:00
|
|
|
}
|
|
|
|
|
2022-02-27 09:56:41 +00:00
|
|
|
set_element(N) ::= set_entity(X) DOTDOT set_entity(Y).
|
2018-04-14 16:07:22 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
N = g_slist_append(NULL, X);
|
|
|
|
N = g_slist_append(N, Y);
|
2015-08-19 03:03:41 +00:00
|
|
|
}
|
2001-02-01 20:21:25 +00:00
|
|
|
|
2022-04-11 19:06:49 +00:00
|
|
|
/* Slices */
|
2022-04-04 15:52:11 +00:00
|
|
|
|
2022-04-11 19:06:49 +00:00
|
|
|
slice(R) ::= entity(E) LBRACKET range_node_list(L) RBRACKET.
|
2022-04-04 15:52:11 +00:00
|
|
|
{
|
2022-04-11 19:06:49 +00:00
|
|
|
R = stnode_new(STTYPE_SLICE, NULL, NULL, NULL);
|
2022-06-23 23:07:42 +00:00
|
|
|
sttype_slice_set(R, E, L);
|
2022-04-04 15:52:11 +00:00
|
|
|
|
|
|
|
/* Delete the list, but not the drange_nodes that
|
|
|
|
* the list contains. */
|
|
|
|
g_slist_free(L);
|
|
|
|
}
|
|
|
|
|
2022-04-07 23:12:56 +00:00
|
|
|
range_node_list(L) ::= RANGE_NODE(N).
|
2022-04-04 15:52:11 +00:00
|
|
|
{
|
2022-06-25 13:20:21 +00:00
|
|
|
char *err_msg = NULL;
|
|
|
|
drange_node *rn = drange_node_from_str(stnode_token(N), &err_msg);
|
|
|
|
if (err_msg != NULL) {
|
|
|
|
FAIL(dfw, N, "%s", err_msg);
|
|
|
|
g_free(err_msg);
|
|
|
|
}
|
|
|
|
L = g_slist_append(NULL, rn);
|
2022-04-07 23:12:56 +00:00
|
|
|
stnode_free(N);
|
2022-04-04 15:52:11 +00:00
|
|
|
}
|
|
|
|
|
2022-04-07 23:12:56 +00:00
|
|
|
range_node_list(L) ::= range_node_list(P) COMMA RANGE_NODE(N).
|
2022-04-04 15:52:11 +00:00
|
|
|
{
|
2022-06-25 13:20:21 +00:00
|
|
|
char *err_msg = NULL;
|
|
|
|
drange_node *rn = drange_node_from_str(stnode_token(N), &err_msg);
|
|
|
|
if (err_msg != NULL) {
|
|
|
|
FAIL(dfw, N, "%s", err_msg);
|
|
|
|
g_free(err_msg);
|
|
|
|
}
|
|
|
|
L = g_slist_append(P, rn);
|
2022-04-07 23:12:56 +00:00
|
|
|
stnode_free(N);
|
2022-04-04 15:52:11 +00:00
|
|
|
}
|
|
|
|
|
2006-05-02 14:26:17 +00:00
|
|
|
/* Functions */
|
|
|
|
|
2021-11-05 06:41:41 +00:00
|
|
|
%code {
|
2021-12-01 19:45:30 +00:00
|
|
|
static stnode_t *
|
2022-04-07 23:12:56 +00:00
|
|
|
new_function(dfwork_t *dfw, stnode_t *node)
|
2021-12-01 19:45:30 +00:00
|
|
|
{
|
2022-06-25 10:25:36 +00:00
|
|
|
const char *name = stnode_token(node);
|
2022-04-07 23:12:56 +00:00
|
|
|
|
2021-12-01 19:45:30 +00:00
|
|
|
df_func_def_t *def = df_func_lookup(name);
|
|
|
|
if (!def) {
|
2022-04-07 12:57:39 +00:00
|
|
|
FAIL(dfw, node, "Function '%s' does not exist", name);
|
2021-12-01 19:45:30 +00:00
|
|
|
}
|
2022-04-07 23:12:56 +00:00
|
|
|
stnode_replace(node, STTYPE_FUNCTION, def);
|
2021-12-01 19:45:30 +00:00
|
|
|
return node;
|
|
|
|
}
|
2021-11-05 06:41:41 +00:00
|
|
|
}
|
|
|
|
|
2006-05-02 14:26:17 +00:00
|
|
|
/* A function can have one or more parameters */
|
2021-09-27 09:33:42 +00:00
|
|
|
function(F) ::= UNPARSED(U) LPAREN function_params(P) RPAREN.
|
2006-05-02 14:26:17 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
F = new_function(dfw, U);
|
|
|
|
sttype_function_set_params(F, P);
|
2006-05-02 14:26:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* A function can have zero parameters. */
|
2021-09-27 09:33:42 +00:00
|
|
|
function(F) ::= UNPARSED(U) LPAREN RPAREN.
|
2006-05-02 14:26:17 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
F = new_function(dfw, U);
|
2006-05-02 14:26:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-16 01:42:20 +00:00
|
|
|
function_params(P) ::= arithmetic_expr(E).
|
2006-05-02 14:26:17 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
P = g_slist_append(NULL, E);
|
2006-05-02 14:26:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-16 01:42:20 +00:00
|
|
|
function_params(P) ::= function_params(L) COMMA arithmetic_expr(E).
|
2006-05-02 14:26:17 +00:00
|
|
|
{
|
2021-12-01 19:45:30 +00:00
|
|
|
P = g_slist_append(L, E);
|
2006-05-02 14:26:17 +00:00
|
|
|
}
|