aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Maudoux <layus.on@gmail.com>2015-07-02 18:39:02 +0200
committerGuillaume Maudoux <layus.on@gmail.com>2015-07-03 13:53:36 +0200
commit65e4dcd69bb618ef2bf07ec128b207df3d9e868a (patch)
tree8446dd04d58add3add1dd746ff2311d16f055fdf
parentdd48c06bb6b9accce92eb7e3806b9cd2af2482cf (diff)
Fix the hack that resets the scanner state.
-rw-r--r--src/libexpr/lexer.l42
-rw-r--r--src/libexpr/parser.y19
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 '"'; }
<STRING>([^\$\"\\]|\$[^\{\"]|\\.)+ {
/* !!! 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;
}
-<STRING>\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
-<STRING>\" { BEGIN(INITIAL); return '"'; }
+<STRING>\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; }
+<STRING>\" { POP_STATE(); return '"'; }
<STRING>. 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; }
<IND_STRING>([^\$\']|\$[^\{\']|\'[^\'\$])+ {
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;
}
-<IND_STRING>\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
-<IND_STRING>\'\' { BEGIN(INITIAL); return IND_STRING_CLOSE; }
+<IND_STRING>\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; }
+<IND_STRING>\'\' { POP_STATE(); return IND_STRING_CLOSE; }
<IND_STRING>\' {
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, vector<Ex
}
-void backToString(yyscan_t scanner);
-void backToIndString(yyscan_t scanner);
-
-
static inline Pos makeCurPos(const YYLTYPE & loc, ParseData * data)
{
return Pos(data->path, 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<Expr *>; $$->push_back($2); }
+ | STR DOLLAR_CURLY expr '}' {
$$ = new vector<Expr *>;
$$->push_back($1);
$$->push_back($3);
}
- | DOLLAR_CURLY expr '}'
- {
- backToString(scanner);
- $$ = new vector<Expr *>;
- $$->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<Expr *>; }
;