%{
#include "command_parse.h"
-
-extern void set_lexer_string (const char *);
-extern void cleanup_lexer (void);
-YY_BUFFER_STATE buffer;
+#define YYSTYPE CMD_YYSTYPE
%}
WORD (\-|\+)?[a-z\*][-+_a-zA-Z0-9\*]*
%option nounput
%option noinput
%option outfile="command_lex.c"
+%option header-file="command_lex.h"
+%option prefix="cmd_yy"
+%option reentrant
+%option bison-bridge
%%
[ /t] /* 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;}
-{IPV6} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return IPV6;}
-{IPV6_PREFIX} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return IPV6_PREFIX;}
-{VARIABLE} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return VARIABLE;}
-{RANGE} {yylval.string = XSTRDUP(MTYPE_TMP, yytext); return RANGE;}
+{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;}
+{IPV6} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return IPV6;}
+{IPV6_PREFIX} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return IPV6_PREFIX;}
+{VARIABLE} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return VARIABLE;}
+{RANGE} {yylval->string = XSTRDUP(MTYPE_TMP, yytext); return RANGE;}
. {return yytext[0];}
%%
-void
-set_lexer_string (const char *string)
+YY_BUFFER_STATE buffer;
+
+void set_lexer_string (yyscan_t *scn, const char *string)
{
- buffer = yy_scan_string (string);
+ *scn = NULL;
+ yylex_init(scn);
+ buffer = yy_scan_string (string, *scn);
}
-void
-cleanup_lexer ()
+void cleanup_lexer (yyscan_t *scn)
{
- yy_delete_buffer (buffer);
+ // yy_delete_buffer (buffer, *scn);
+ yylex_destroy(*scn);
}
*/
%{
+
+typedef union CMD_YYSTYPE CMD_YYSTYPE;
+#define YYSTYPE CMD_YYSTYPE
+#include "command_lex.h"
+
// compile with debugging facilities
#define YYDEBUG 1
%}
+%define api.pure full
+%define api.prefix {cmd_yy}
+
/* names for generated header and parser files */
%defines "command_parse.h"
%output "command_parse.c"
#include "log.h"
#include "graph.h"
- extern int
- yylex (void);
-
- extern void
- set_lexer_string (const char *);
-
- extern void
- cleanup_lexer (void);
-
struct parser_ctx {
+ yyscan_t scanner;
+
struct cmd_element *el;
struct graph *graph;
/* functionality this unit exports */
%code provides {
-
/* maximum length of a number, lexer will not match anything longer */
#define DECIMAL_STRLEN_MAX 20
}
%type <subgraph> compound_token
%code {
+
+ extern void set_lexer_string (yyscan_t *scn, const char *string);
+ extern void cleanup_lexer (yyscan_t *scn);
+
/* bison declarations */
void
- yyerror (struct parser_ctx *ctx, char const *msg);
+ cmd_yyerror (struct parser_ctx *ctx, char const *msg);
/* subgraph semantic value */
struct subgraph {
static void
cleanup (struct parser_ctx *ctx);
+
+ #define scanner ctx->scanner
}
/* yyparse parameters */
-%parse-param { struct parser_ctx *ctx }
+%lex-param {yyscan_t scanner}
+%parse-param {struct parser_ctx *ctx}
/* called automatically before yyparse */
%initial-action {
ctx->startnode = vector_slot (ctx->graph->nodes, 0);
- /* set string to parse */
- set_lexer_string (ctx->el->string);
-
/* copy docstring and keep a pointer to the copy */
if (ctx->el->doc)
{
token->max = strtoll (yylval.string, &yylval.string, 10);
// validate range
- if (token->min > token->max) yyerror (ctx, "Invalid range.");
+ if (token->min > token->max) cmd_yyerror (ctx, "Invalid range.");
free ($1);
}
%%
+#undef scanner
+
void
command_parse_format (struct graph *graph, struct cmd_element *cmd)
{
// set to 1 to enable parser traces
yydebug = 0;
+ set_lexer_string (&ctx.scanner, cmd->string);
+
// parse command into DFA
- yyparse (&ctx);
+ cmd_yyparse (&ctx);
+
+ /* cleanup lexer */
+ cleanup_lexer (&ctx.scanner);
// cleanup
cleanup (&ctx);
/* free resources */
free (ctx->docstr_start);
- /* cleanup lexer */
- cleanup_lexer ();
-
/* clear state pointers */
ctx->currnode = NULL;
ctx->docstr_start = ctx->docstr = NULL;
graph_new_node (ctx->graph, element, (void (*)(void *)) &del_cmd_element);
if (node_adjacent (finalnode, end_token_node))
- yyerror (ctx, "Duplicate command.");
+ cmd_yyerror (ctx, "Duplicate command.");
graph_add_edge (finalnode, end_token_node);
graph_add_edge (end_token_node, end_element_node);