forked from osmocom/wireshark
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:
parent
77ef21f86e
commit
af22c743bd
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue