about summary refs log tree commit diff
path: root/src/libexpr/lexer.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/lexer.l')
-rw-r--r--src/libexpr/lexer.l42
1 files changed, 15 insertions, 27 deletions
diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l
index 7051909008d1..7483e5cc4acb 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);
-}
-
-}