# #
#############################################################################*/
-%parse-param {Pakfire pakfire} {PakfireParser* result} {struct pakfire_parser_error** error}
+%lex-param {yyscan_t* scanner}
+
+%parse-param
+ {yyscan_t* scanner}
+ {PakfireParser* parser}
+ {Pakfire pakfire}
+ {struct pakfire_parser_error** error}
+
+// Make the parser reentrant
+%define api.pure full
// Generate verbose error messages
%define parse.error verbose
int yydebug = 1;
#endif
+typedef void* yyscan_t;
+extern int yylex_init(yyscan_t* scanner);
+int yylex_destroy(yyscan_t scanner);
+
typedef struct yy_buffer_state* YY_BUFFER_STATE;
-extern YY_BUFFER_STATE yy_scan_bytes(const char* buffer, size_t len);
-extern void yy_delete_buffer(YY_BUFFER_STATE buffer);
+extern YY_BUFFER_STATE yy_scan_bytes(const char* buffer, size_t len, yyscan_t scanner);
+extern void yy_delete_buffer(YY_BUFFER_STATE buffer, yyscan_t scanner);
-extern int yylex();
-extern int yyparse();
+#include "grammar.h"
+
+extern int yylex (YYSTYPE* yylval_param, yyscan_t yyscanner);
extern int num_lines;
OP_EQUALS = 0,
};
-static void yyerror(Pakfire pakfire, PakfireParser* result,
+static void yyerror(yyscan_t* scanner, PakfireParser* parser, Pakfire pakfire,
struct pakfire_parser_error** error, const char* s) {
ERROR(pakfire, "Error (line %d): %s\n", num_lines, s);
// Create a new error object
if (error) {
- int r = pakfire_parser_error_create(error, *result, NULL, num_lines, s);
+ int r = pakfire_parser_error_create(error, *parser, NULL, num_lines, s);
if (r) {
ERROR(pakfire, "Could not create error object: %s\n", strerror(errno));
}
if (!$$)
ABORT;
- if (!*result)
- *result = pakfire_parser_ref($$);
+ if (!*parser)
+ *parser = pakfire_parser_ref($$);
}
| grammar declaration
{
if_stmt : T_IF T_STRING T_EQUALS T_STRING T_EOL subgrammar else_stmt T_END T_EOL
{
- $$ = make_if_stmt(pakfire, result, OP_EQUALS, $2, $4, $6, $7);
+ $$ = make_if_stmt(pakfire, parser, OP_EQUALS, $2, $4, $6, $7);
pakfire_parser_unref($6);
pakfire_parser_unref($7);
int pakfire_parser_parse_data(PakfireParser parent, const char* data, size_t len,
struct pakfire_parser_error** error) {
Pakfire pakfire = pakfire_parser_get_pakfire(parent);
+ yyscan_t scanner;
#ifdef ENABLE_DEBUG
DEBUG(pakfire, "Parsing the following data (%zu):\n%.*s\n",
clock_t t_start = clock();
#endif
+ // Initialise scanner
+ yylex_init(&scanner);
+
// Create a new sub-parser
PakfireParser parser = NULL;
num_lines = 1;
- YY_BUFFER_STATE buffer = yy_scan_bytes(data, len);
- int r = yyparse(pakfire, &parser, error);
- yy_delete_buffer(buffer);
+ YY_BUFFER_STATE buffer = yy_scan_bytes(data, len, scanner);
+ int r = yyparse(scanner, &parser, pakfire, error);
+ yy_delete_buffer(buffer, scanner);
// If everything was parsed successfully, we merge the sub-parser into
// the parent parser. That way, it will be untouched if something could
// Cleanup
pakfire_unref(pakfire);
+ yylex_destroy(scanner);
return r;
}
# #
#############################################################################*/
+%option bison-bridge
%option noinput noyywrap yylineno
%option nodefault
+%option reentrant
%option stack noyy_top_state
%option warn
/* %option debug */
%{
-#define YY_DECL int yylex()
+#define YY_DECL int yylex (YYSTYPE* yylval_param, yyscan_t yyscanner)
int num_lines;
// Jump back into indentation processing after a newline
current_indent = 0;
- yy_push_state(INDENT);
+ yy_push_state(INDENT, yyscanner);
return T_EOL;
}
<NOKEYWORD>{keys}$ {
// Leave NOKEYWORD immediately again
- yy_pop_state();
+ yy_pop_state(yyscanner);
// Copy the value
- yylval.string = strdup(yytext);
+ yylval->string = strdup(yytext);
// Enter into READLINES mode
- yy_push_state(READLINES);
+ yy_push_state(READLINES, yyscanner);
return T_KEY;
}
<NOKEYWORD>{keys} {
// Leave NOKEYWORD immediately again
- yy_pop_state();
+ yy_pop_state(yyscanner);
// Copy the value
- yylval.string = strdup(yytext);
+ yylval->string = strdup(yytext);
return T_KEY;
}
}
^{subparsers}$ {
- yylval.string = strdup(yytext);
+ yylval->string = strdup(yytext);
return T_SUBPARSER;
}
{named_subparsers} {
- yy_push_state(READLINE);
+ yy_push_state(READLINE, yyscanner);
- yylval.string = strdup(yytext);
+ yylval->string = strdup(yytext);
return T_SUBPARSER;
}
{quoted_string} {
// Remove quotes
- yylval.string = unquote(yytext);
+ yylval->string = unquote(yytext);
return T_STRING;
}
"=" {
// Read everything after this
- yy_push_state(READLINE);
+ yy_push_state(READLINE, yyscanner);
return T_ASSIGN;
}
"+=" {
// Read everything after this
- yy_push_state(READLINE);
+ yy_push_state(READLINE, yyscanner);
return T_APPEND;
}
yyless(0);
// None of the keywords have matched
- yy_push_state(NOKEYWORD);
+ yy_push_state(NOKEYWORD, yyscanner);
}
<READLINE>.*\\\n {
<READLINE>.*$ {
// Return to caller
- yy_pop_state();
+ yy_pop_state(yyscanner);
// Copy the entire string
- yylval.string = copy_string(yytext);
+ yylval->string = copy_string(yytext);
return T_STRING;
}
// If we found the same or less indentation we go back
// to the previous state and continue parsing there
} else {
- yy_pop_state();
+ yy_pop_state(yyscanner);
}
}
// <-- ?
else if (current_indent < readline_indent) {
readline_indent = 0;
- yy_pop_state();
+ yy_pop_state(yyscanner);
return T_OUTDENT;
// The indentation stayed the same, read the next line
} else {
- yy_push_state(READLINE);
+ yy_push_state(READLINE, yyscanner);
}
}
// --> - More indentation?
if (current_indent > indent_level) {
indent_level++;
- yy_pop_state();
+ yy_pop_state(yyscanner);
return T_INDENT;
// <-- - If indentation has become less
} else if (current_indent < indent_level) {
indent_level--;
- yy_pop_state();
+ yy_pop_state(yyscanner);
return T_OUTDENT;
// If indentation has stayed the same
} else {
- yy_pop_state();
+ yy_pop_state(yyscanner);
}
}