dfilter: Refactor error location for expressions

Underline the whole expression for errors, not just the token.
Implement it for all expressions.
This commit is contained in:
João Valverde 2022-12-28 21:52:54 +00:00
parent 77ef21f86e
commit af22c743bd
4 changed files with 92 additions and 78 deletions

View File

@ -106,26 +106,28 @@ expr(X) ::= expr(Y) TEST_AND(T) expr(Z).
{
X = T;
sttype_oper_set2(X, STNODE_OP_AND, Y, Z);
stnode_merge_location(X, Y, Z);
}
expr(X) ::= expr(Y) TEST_OR(T) expr(Z).
{
X = T;
sttype_oper_set2(X, STNODE_OP_OR, Y, Z);
stnode_merge_location(X, Y, Z);
}
expr(X) ::= TEST_NOT(T) expr(Y).
{
X = T;
sttype_oper_set1(X, STNODE_OP_NOT, Y);
stnode_merge_location(X, T, Y);
}
/* Any expression inside parens is simply that expression */
expr(X) ::= LPAREN(L) expr(Y) RPAREN(R).
{
X = Y;
df_loc_t loc = stnode_merge_location(L, Y, R, (stnode_t *)NULL);
stnode_set_location(X, loc);
stnode_merge_location(X, L, R);
stnode_free(L);
stnode_free(R);
}
@ -152,49 +154,57 @@ named_field(X) ::= IDENTIFIER(U).
stnode_replace(X, STTYPE_FIELD, hfinfo);
}
layered_field(R) ::= named_field(F).
layered_field(X) ::= named_field(F).
{
R = F;
X = F;
}
layered_field(R) ::= named_field(F) HASH LBRACKET range_node_list(L) RBRACKET.
layered_field(X) ::= named_field(F) HASH LBRACKET range_node_list(L) RBRACKET(R).
{
R = F;
sttype_field_set_range(R, L);
X = F;
sttype_field_set_range(X, L);
g_slist_free(L);
stnode_merge_location(X, F, R);
stnode_free(R);
}
layered_field(R) ::= named_field(F) HASH INTEGER(N).
layered_field(X) ::= named_field(F) HASH INTEGER(N).
{
R = F;
X = F;
char *err_msg = NULL;
drange_node *range = drange_node_from_str(stnode_token(N), &err_msg);
if (err_msg != NULL) {
FAIL(dfw, N, "%s", err_msg);
g_free(err_msg);
}
sttype_field_set_range1(R, range);
sttype_field_set_range1(X, range);
stnode_merge_location(X, F, N);
stnode_free(N);
}
rawable_field(R) ::= layered_field(F).
rawable_field(X) ::= layered_field(F).
{
R = F;
X = F;
}
rawable_field(R) ::= ATSIGN layered_field(F).
rawable_field(X) ::= ATSIGN(A) layered_field(F).
{
R = F;
sttype_field_set_raw(R, TRUE);
X = F;
sttype_field_set_raw(X, TRUE);
stnode_merge_location(X, A, F);
stnode_free(A);
}
reference(R) ::= DOLLAR LBRACE rawable_field(F) RBRACE.
reference(X) ::= DOLLAR(D) LBRACE rawable_field(F) RBRACE(R).
{
/* 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));
sttype_field_set_raw(R, sttype_field_raw(F));
X = stnode_new(STTYPE_REFERENCE, sttype_field_hfinfo(F), NULL, stnode_location(F));
sttype_field_set_drange(X, sttype_field_drange_steal(F));
sttype_field_set_raw(X, sttype_field_raw(F));
stnode_merge_location(X, D, R);
stnode_free(F);
stnode_free(D);
stnode_free(R);
}
entity(E) ::= atom(A). { E = A; }
@ -208,58 +218,66 @@ arithmetic_expr(T) ::= entity(N).
T = N;
}
arithmetic_expr(T) ::= PLUS arithmetic_expr(N). [UNARY_PLUS]
arithmetic_expr(T) ::= PLUS(P) arithmetic_expr(N). [UNARY_PLUS]
{
T = N;
stnode_merge_location(T, P, N);
stnode_free(P);
}
arithmetic_expr(T) ::= MINUS(M) arithmetic_expr(N). [UNARY_MINUS]
{
T = M;
sttype_oper_set1(T, STNODE_OP_UNARY_MINUS, N);
stnode_merge_location(T, M, N);
}
arithmetic_expr(T) ::= arithmetic_expr(F) BITWISE_AND(O) arithmetic_expr(M).
{
T = O;
sttype_oper_set2(T, STNODE_OP_BITWISE_AND, F, M);
stnode_merge_location(T, F, M);
}
arithmetic_expr(T) ::= arithmetic_expr(F) PLUS(O) arithmetic_expr(M).
{
T = O;
sttype_oper_set2(T, STNODE_OP_ADD, F, M);
stnode_merge_location(T, F, M);
}
arithmetic_expr(T) ::= arithmetic_expr(F) MINUS(O) arithmetic_expr(M).
{
T = O;
sttype_oper_set2(T, STNODE_OP_SUBTRACT, F, M);
stnode_merge_location(T, F, M);
}
arithmetic_expr(T) ::= arithmetic_expr(F) STAR(O) arithmetic_expr(M).
{
T = O;
sttype_oper_set2(T, STNODE_OP_MULTIPLY, F, M);
stnode_merge_location(T, F, M);
}
arithmetic_expr(T) ::= arithmetic_expr(F) RSLASH(O) arithmetic_expr(M).
{
T = O;
sttype_oper_set2(T, STNODE_OP_DIVIDE, F, M);
stnode_merge_location(T, F, M);
}
arithmetic_expr(T) ::= arithmetic_expr(F) PERCENT(O) arithmetic_expr(M).
{
T = O;
sttype_oper_set2(T, STNODE_OP_MODULO, F, M);
stnode_merge_location(T, F, M);
}
arithmetic_expr(T) ::= LBRACE(L) arithmetic_expr(F) RBRACE(R).
{
T = F;
df_loc_t loc = stnode_merge_location(L, F, R, (stnode_t *)NULL);
stnode_set_location(T, loc);
stnode_merge_location(T, L, R);
stnode_free(L);
stnode_free(R);
}
@ -317,6 +335,7 @@ comparison_test(T) ::= arithmetic_expr(E) cmp_op(O) arithmetic_expr(F).
{
T = O;
sttype_oper_set2_args(O, E, F);
stnode_merge_location(T, E, F);
}
/* 'a == b == c' or 'a < b <= c <= d < e' */
@ -334,6 +353,7 @@ comparison_test(T) ::= arithmetic_expr(E) cmp_op(O) comparison_test(R).
T = stnode_new_empty(STTYPE_TEST);
sttype_oper_set2(T, STNODE_OP_AND, L, R);
stnode_merge_location(T, E, R);
}
relation_test(T) ::= comparison_test(C). { T = C; }
@ -342,18 +362,21 @@ relation_test(T) ::= entity(E) TEST_CONTAINS(L) entity(F).
{
T = L;
sttype_oper_set2(T, STNODE_OP_CONTAINS, E, F);
stnode_merge_location(T, E, F);
}
relation_test(T) ::= entity(E) TEST_MATCHES(L) entity(F).
{
T = L;
sttype_oper_set2(T, STNODE_OP_MATCHES, E, F);
stnode_merge_location(T, E, F);
}
relation_test(T) ::= entity(E) TEST_IN(O) set(S).
{
T = O;
sttype_oper_set2(T, STNODE_OP_IN, E, S);
stnode_merge_location(T, E, S);
}
relation_test(T) ::= entity(E) TEST_NOT(P) TEST_IN(O) set(S).
@ -361,36 +384,28 @@ relation_test(T) ::= entity(E) TEST_NOT(P) TEST_IN(O) set(S).
T = P;
sttype_oper_set2(O, STNODE_OP_IN, E, S);
sttype_oper_set1(T, STNODE_OP_NOT, O);
stnode_merge_location(T, E, S);
}
relation(R) ::= relation_test(T). { R = T; }
relation(R) ::= ANY relation_test(T).
relation(R) ::= ANY(A) relation_test(T).
{
R = T;
sttype_test_set_match(R, STNODE_MATCH_ANY);
stnode_merge_location(R, A, T);
stnode_free(A);
}
relation(R) ::= ALL relation_test(T).
relation(R) ::= ALL(A) relation_test(T).
{
R = T;
sttype_test_set_match(R, STNODE_MATCH_ALL);
stnode_merge_location(R, A, T);
stnode_free(A);
}
set(S) ::= LBRACE set_list(L) RBRACE.
{
S = stnode_new(STTYPE_SET, L, NULL, DFILTER_LOC_EMPTY);
}
set_list(L) ::= set_element_list(N).
{
L = g_slist_concat(NULL, N);
}
set_list(L) ::= set_list(P) COMMA set_element_list(N).
{
L = g_slist_concat(P, N);
}
/* Sets */
set_entity(N) ::= entity(E).
{
@ -401,11 +416,14 @@ set_entity(N) ::= MINUS(M) entity(E).
{
N = M;
sttype_oper_set1(N, STNODE_OP_UNARY_MINUS, E);
stnode_merge_location(N, M, E);
}
set_entity(N) ::= PLUS entity(E).
set_entity(N) ::= PLUS(P) entity(E).
{
N = E;
stnode_merge_location(N, P, E);
stnode_free(P);
}
set_element_list(N) ::= set_entity(X).
@ -420,6 +438,24 @@ set_element_list(N) ::= set_entity(X) DOTDOT set_entity(Y).
N = g_slist_append(N, Y);
}
set_list(L) ::= set_element_list(N).
{
L = g_slist_concat(NULL, N);
}
set_list(L) ::= set_list(P) COMMA set_element_list(N).
{
L = g_slist_concat(P, N);
}
set(S) ::= LBRACE(LB) set_list(L) RBRACE(RB).
{
S = stnode_new(STTYPE_SET, L, NULL, DFILTER_LOC_EMPTY);
stnode_merge_location(S, LB, RB);
stnode_free(LB);
stnode_free(RB);
}
/* Slices */
slice(R) ::= entity(E) LBRACKET range_node_list(L) RBRACKET.
@ -474,13 +510,11 @@ range_node_list(L) ::= range_node_list(P) COMMA RANGE_NODE(N).
}
/* A function can have one or more parameters */
function(F) ::= IDENTIFIER(U) LPAREN(L) func_params_list(P) RPAREN(R).
function(F) ::= IDENTIFIER(U) LPAREN func_params_list(P) RPAREN(R).
{
F = new_function(dfw, U);
sttype_function_set_params(F, P);
df_loc_t loc = stnode_merge_location(F, L, R, (stnode_t *)NULL);
stnode_set_location(F, loc);
stnode_free(L);
stnode_merge_location(F, U, R);
stnode_free(R);
}
@ -490,12 +524,10 @@ function ::= CONSTANT(U) LPAREN func_params_list RPAREN.
}
/* A function can have zero parameters. */
function(F) ::= IDENTIFIER(U) LPAREN(L) RPAREN(R).
function(F) ::= IDENTIFIER(U) LPAREN RPAREN(R).
{
F = new_function(dfw, U);
df_loc_t loc = stnode_merge_location(F, L, R, (stnode_t *)NULL);
stnode_set_location(F, loc);
stnode_free(L);
stnode_merge_location(F, U, R);
stnode_free(R);
}

View File

@ -278,7 +278,6 @@ sttype_oper_set1(stnode_t *node, stnode_op_t op, stnode_t *val1)
oper->op = op;
oper->val1 = val1;
oper->val2 = NULL;
node->location = stnode_merge_location(node, val1, (stnode_t *)NULL);
}
void
@ -291,7 +290,6 @@ sttype_oper_set2(stnode_t *node, stnode_op_t op, stnode_t *val1, stnode_t *val2)
oper->op = op;
oper->val1 = val1;
oper->val2 = val2;
node->location = stnode_merge_location(node, val1, val2, (stnode_t *)NULL);
}
void
@ -305,7 +303,6 @@ sttype_oper_set1_args(stnode_t *node, stnode_t *val1)
ws_assert(num_operands(oper->op) == 1);
oper->val1 = val1;
oper->val2 = NULL;
node->location = stnode_merge_location(node, val1, (stnode_t *)NULL);
}
void
@ -319,7 +316,6 @@ sttype_oper_set2_args(stnode_t *node, stnode_t *val1, stnode_t *val2)
ws_assert(num_operands(oper->op) == 2);
oper->val1 = val1;
oper->val2 = val2;
node->location = stnode_merge_location(node, val1, val2, (stnode_t *)NULL);
}
void

View File

@ -258,33 +258,19 @@ stnode_set_location(stnode_t *node, df_loc_t loc)
/* Finds the first and last location from a set and creates
* a new location from start of first (col_start) to end of
* last (col_start + col_len). */
df_loc_t
stnode_merge_location(stnode_t *st, ...)
* last (col_start + col_len). Sets the result to dst. */
void
stnode_merge_location(stnode_t *dst, stnode_t *n1, stnode_t *n2)
{
df_loc_t first, last, loc;
df_loc_t result;
va_list ap;
df_loc_t first, last;
df_loc_t loc2;
first = last = stnode_location(st);
va_start(ap, st);
while ((st = va_arg(ap, stnode_t *)) != NULL) {
loc = stnode_location(st);
if (loc.col_start >= 0) {
if (loc.col_start < first.col_start) {
first = loc;
}
else if (loc.col_start > last.col_start) {
last = loc;
}
}
}
va_end(ap);
result.col_start = first.col_start;
result.col_len = last.col_start - first.col_start + last.col_len;
return result;
first = last = stnode_location(n1);
loc2 = stnode_location(n2);
if (loc2.col_start >= 0 && loc2.col_start > first.col_start)
last = loc2;
dst->location.col_start = first.col_start;
dst->location.col_len = last.col_start - first.col_start + last.col_len;
}
#define IS_OPERATOR(node) \

View File

@ -159,8 +159,8 @@ stnode_location(stnode_t *node);
void
stnode_set_location(stnode_t *node, df_loc_t loc);
df_loc_t
stnode_merge_location(stnode_t *n1, ...);
void
stnode_merge_location(stnode_t *dst, stnode_t *n1, stnode_t *n2);
const char *
stnode_tostr(stnode_t *node, gboolean pretty);