From 65e4dcd69bb618ef2bf07ec128b207df3d9e868a Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Thu, 2 Jul 2015 18:39:02 +0200 Subject: [PATCH] Fix the hack that resets the scanner state. --- src/libexpr/lexer.l | 42 +++++++++++++++--------------------------- src/libexpr/parser.y | 19 ++++--------------- 2 files changed, 19 insertions(+), 42 deletions(-) diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l index 705190900..7483e5cc4 100644 --- a/src/libexpr/lexer.l +++ b/src/libexpr/lexer.l @@ -1,6 +1,9 @@ %option reentrant bison-bridge bison-locations %option noyywrap %option never-interactive +%option stack +%option nodefault +%option nounput noyy_top_state %x STRING @@ -74,6 +77,9 @@ static Expr * unescapeStr(SymbolTable & symbols, const char * s) #define YY_USER_INIT initLoc(yylloc) #define YY_USER_ACTION adjustLoc(yylloc, yytext, yyleng); +#define PUSH_STATE(state) yy_push_state(state, yyscanner) +#define POP_STATE() yy_pop_state(yyscanner) + %} @@ -118,9 +124,11 @@ or { return OR_KW; } return INT; } -\$\{ { return DOLLAR_CURLY; } +\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; } +\{ { PUSH_STATE(INITIAL); return '{'; } +\} { POP_STATE(); return '}'; } -\" { BEGIN(STRING); return '"'; } +\" { PUSH_STATE(STRING); return '"'; } ([^\$\"\\]|\$[^\{\"]|\\.)+ { /* !!! Not quite right: we want a follow restriction on "$", it shouldn't be followed by a "{". Right now @@ -130,11 +138,11 @@ or { return OR_KW; } yylval->e = unescapeStr(data->symbols, yytext); return STR; } -\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; } -\" { BEGIN(INITIAL); return '"'; } +\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; } +\" { POP_STATE(); return '"'; } . return yytext[0]; /* just in case: shouldn't be reached */ -\'\'(\ *\n)? { BEGIN(IND_STRING); return IND_STRING_OPEN; } +\'\'(\ *\n)? { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; } ([^\$\']|\$[^\{\']|\'[^\'\$])+ { yylval->e = new ExprIndStr(yytext); return IND_STR; @@ -151,8 +159,8 @@ or { return OR_KW; } yylval->e = unescapeStr(data->symbols, yytext + 2); return IND_STR; } -\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; } -\'\' { BEGIN(INITIAL); return IND_STRING_CLOSE; } +\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; } +\'\' { POP_STATE(); return IND_STRING_CLOSE; } \' { yylval->e = new ExprIndStr("'"); return IND_STR; @@ -173,23 +181,3 @@ or { return OR_KW; } %% - -namespace nix { - -/* Horrible, disgusting hack: allow the parser to set the scanner - start condition back to STRING. Necessary in interpolations like - "foo${expr}bar"; after the close brace we have to go back to the - STRING state. */ -void backToString(yyscan_t scanner) -{ - struct yyguts_t * yyg = (struct yyguts_t *) scanner; - BEGIN(STRING); -} - -void backToIndString(yyscan_t scanner) -{ - struct yyguts_t * yyg = (struct yyguts_t *) scanner; - BEGIN(IND_STRING); -} - -} diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 26168b2ed..1f830b7e3 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -216,10 +216,6 @@ static Expr * stripIndentation(const Pos & pos, SymbolTable & symbols, vectorpath, loc.first_line, loc.first_column); @@ -404,25 +400,18 @@ string_parts string_parts_interpolated : string_parts_interpolated STR { $$ = $1; $1->push_back($2); } - | string_parts_interpolated DOLLAR_CURLY expr '}' { backToString(scanner); $$ = $1; $1->push_back($3); } - | STR DOLLAR_CURLY expr '}' - { - backToString(scanner); + | string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->push_back($3); } + | DOLLAR_CURLY expr '}' { $$ = new vector; $$->push_back($2); } + | STR DOLLAR_CURLY expr '}' { $$ = new vector; $$->push_back($1); $$->push_back($3); } - | DOLLAR_CURLY expr '}' - { - backToString(scanner); - $$ = new vector; - $$->push_back($2); - } ; ind_string_parts : ind_string_parts IND_STR { $$ = $1; $1->push_back($2); } - | ind_string_parts DOLLAR_CURLY expr '}' { backToIndString(scanner); $$ = $1; $1->push_back($3); } + | ind_string_parts DOLLAR_CURLY expr '}' { $$ = $1; $1->push_back($3); } | { $$ = new vector; } ;