summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/command_lex.l12
-rw-r--r--lib/command_parse.y52
2 files changed, 53 insertions, 11 deletions
diff --git a/lib/command_lex.l b/lib/command_lex.l
index e245fc497..703596b43 100644
--- a/lib/command_lex.l
+++ b/lib/command_lex.l
@@ -24,6 +24,11 @@
%{
#include "command_parse.h"
+
+#define YY_USER_ACTION yylloc->last_column += yyleng;
+#define LOC_STEP \
+ yylloc->first_column = yylloc->last_column; \
+ yylloc->first_line = yylloc->last_line;
%}
WORD (\-|\+)?[a-z0-9\*][-+_a-zA-Z0-9\*]*
@@ -45,9 +50,14 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
%option prefix="cmd_yy"
%option reentrant
%option bison-bridge
+%option bison-locations
%%
-[ \t] /* ignore whitespace */;
+%{
+ LOC_STEP;
+%}
+
+[ \t]+ LOC_STEP /* ignore whitespace */;
{WORD} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return WORD;}
{IPV4} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return IPV4;}
{IPV4_PREFIX} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return IPV4_PREFIX;}
diff --git a/lib/command_parse.y b/lib/command_parse.y
index db4709172..cbc7ce975 100644
--- a/lib/command_parse.y
+++ b/lib/command_parse.y
@@ -27,6 +27,8 @@
#define YYDEBUG 1
%}
+%locations
+%define parse.error verbose
%define api.pure full
/* define api.prefix {cmd_yy} */
@@ -49,6 +51,7 @@
#include "graph.h"
#define YYSTYPE CMD_YYSTYPE
+ #define YYLTYPE CMD_YYLTYPE
struct parser_ctx;
/* subgraph semantic value */
@@ -108,7 +111,7 @@
/* bison declarations */
void
- cmd_yyerror (struct parser_ctx *ctx, char const *msg);
+ cmd_yyerror (CMD_YYLTYPE *locp, struct parser_ctx *ctx, char const *msg);
/* helper functions for parser */
static char *
@@ -130,7 +133,7 @@
char *doc);
static void
- terminate_graph (struct parser_ctx *ctx,
+ terminate_graph (CMD_YYLTYPE *locp, struct parser_ctx *ctx,
struct graph_node *);
static void
@@ -169,7 +172,7 @@ start:
cmd_token_seq
{
// tack on the command element
- terminate_graph (ctx, ctx->currnode);
+ terminate_graph (&@1, ctx, ctx->currnode);
}
| cmd_token_seq placeholder_token '.' '.' '.'
{
@@ -183,7 +186,7 @@ start:
add_edge_dedup (ctx->currnode, ctx->currnode);
// tack on the command element
- terminate_graph (ctx, ctx->currnode);
+ terminate_graph (&@1, ctx, ctx->currnode);
}
;
@@ -255,7 +258,7 @@ placeholder_token:
token->max = strtoll (yylval.string, &yylval.string, 10);
// validate range
- if (token->min > token->max) cmd_yyerror (ctx, "Invalid range.");
+ if (token->min > token->max) cmd_yyerror (&@1, ctx, "Invalid range.");
free ($1);
}
@@ -352,11 +355,39 @@ command_parse_format (struct graph *graph, struct cmd_element *cmd)
/* parser helper functions */
void
-yyerror (struct parser_ctx *ctx, char const *msg)
+yyerror (CMD_YYLTYPE *loc, struct parser_ctx *ctx, char const *msg)
{
+ char *tmpstr = strdup(ctx->el->string);
+ char *line, *eol;
+ char spacing[256];
+ int lineno = 0;
+
zlog_err ("%s: FATAL parse error: %s", __func__, msg);
- zlog_err ("while parsing this command definition: \n\t%s\n", ctx->el->string);
- //exit(EXIT_FAILURE);
+ zlog_err ("%s: %d:%d-%d of this command definition:", __func__, loc->first_line, loc->first_column, loc->last_column);
+
+ line = tmpstr;
+ do {
+ lineno++;
+ eol = strchr(line, '\n');
+ if (eol)
+ *eol++ = '\0';
+
+ zlog_err ("%s: | %s", __func__, line);
+ if (lineno == loc->first_line && lineno == loc->last_line
+ && loc->first_column < (int)sizeof(spacing) - 1
+ && loc->last_column < (int)sizeof(spacing) - 1) {
+
+ int len = loc->last_column - loc->first_column;
+ if (len == 0)
+ len = 1;
+
+ memset(spacing, ' ', loc->first_column - 1);
+ memset(spacing + loc->first_column - 1, '^', len);
+ spacing[loc->first_column - 1 + len] = '\0';
+ zlog_err ("%s: | %s", __func__, spacing);
+ }
+ } while ((line = eol));
+ free(tmpstr);
}
static void
@@ -371,7 +402,8 @@ cleanup (struct parser_ctx *ctx)
}
static void
-terminate_graph (struct parser_ctx *ctx, struct graph_node *finalnode)
+terminate_graph (CMD_YYLTYPE *locp, struct parser_ctx *ctx,
+ struct graph_node *finalnode)
{
// end of graph should look like this
// * -> finalnode -> END_TKN -> cmd_element
@@ -385,7 +417,7 @@ terminate_graph (struct parser_ctx *ctx, struct graph_node *finalnode)
graph_new_node (ctx->graph, element, NULL);
if (node_adjacent (finalnode, end_token_node))
- cmd_yyerror (ctx, "Duplicate command.");
+ cmd_yyerror (locp, ctx, "Duplicate command.");
graph_add_edge (finalnode, end_token_node);
graph_add_edge (end_token_node, end_element_node);