about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/lexer.l24
-rw-r--r--tests/lexer.nix2
-rw-r--r--tests/lexer.sh3
-rw-r--r--tests/local.mk2
4 files changed, 23 insertions, 8 deletions
diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l
index 1f2957ec71ad..478f4164106a 100644
--- a/src/libexpr/lexer.l
+++ b/src/libexpr/lexer.l
@@ -8,6 +8,7 @@
 
 %x STRING
 %x IND_STRING
+%x INSIDE_DOLLAR_CURLY
 
 
 %{
@@ -93,6 +94,8 @@ URI         [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~
 
 %%
 
+<INITIAL,INSIDE_DOLLAR_CURLY>{
+
 
 if          { return IF; }
 then        { return THEN; }
@@ -124,11 +127,15 @@ or          { return OR_KW; }
               return INT;
             }
 
-\$\{        { PUSH_STATE(INITIAL); return DOLLAR_CURLY; }
-\{          { PUSH_STATE(INITIAL); return '{'; }
-\}          { POP_STATE(); return '}'; }
+\$\{        { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; }
+}
+
+\}                           { return '}'; }
+<INSIDE_DOLLAR_CURLY>\}      { POP_STATE(); return '}'; }
+\{                           { return '{'; }
+<INSIDE_DOLLAR_CURLY>\{      { PUSH_STATE(INSIDE_DOLLAR_CURLY); return '{'; }
 
-\"          { PUSH_STATE(STRING); return '"'; }
+<INITIAL,INSIDE_DOLLAR_CURLY>\"          { PUSH_STATE(STRING); return '"'; }
 <STRING>([^\$\"\\]|\$[^\{\"\\]|\\.|\$\\.)*\$/\" |
 <STRING>([^\$\"\\]|\$[^\{\"\\]|\\.|\$\\.)+ {
               /* It is impossible to match strings ending with '$' with one
@@ -137,11 +144,11 @@ or          { return OR_KW; }
               yylval->e = unescapeStr(data->symbols, yytext);
               return STR;
             }
-<STRING>\$\{  { PUSH_STATE(INITIAL); return DOLLAR_CURLY; }
+<STRING>\$\{  { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; }
 <STRING>\"  { POP_STATE(); return '"'; }
 <STRING>.   return yytext[0]; /* just in case: shouldn't be reached */
 
-\'\'(\ *\n)?     { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; }
+<INITIAL,INSIDE_DOLLAR_CURLY>\'\'(\ *\n)?     { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; }
 <IND_STRING>([^\$\']|\$[^\{\']|\'[^\'\$])+ {
                    yylval->e = new ExprIndStr(yytext);
                    return IND_STR;
@@ -158,7 +165,7 @@ or          { return OR_KW; }
                    yylval->e = unescapeStr(data->symbols, yytext + 2);
                    return IND_STR;
                  }
-<IND_STRING>\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; }
+<IND_STRING>\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; }
 <IND_STRING>\'\' { POP_STATE(); return IND_STRING_CLOSE; }
 <IND_STRING>\'   {
                    yylval->e = new ExprIndStr("'");
@@ -166,6 +173,8 @@ or          { return OR_KW; }
                  }
 <IND_STRING>.    return yytext[0]; /* just in case: shouldn't be reached */
 
+<INITIAL,INSIDE_DOLLAR_CURLY>{
+
 {PATH}      { yylval->path = strdup(yytext); return PATH; }
 {HPATH}     { yylval->path = strdup(yytext); return HPATH; }
 {SPATH}     { yylval->path = strdup(yytext); return SPATH; }
@@ -177,6 +186,7 @@ or          { return OR_KW; }
 
 .           return yytext[0];
 
+}
 
 %%
 
diff --git a/tests/lexer.nix b/tests/lexer.nix
new file mode 100644
index 000000000000..05c78b3016d3
--- /dev/null
+++ b/tests/lexer.nix
@@ -0,0 +1,2 @@
+let const = a: "const"; in
+''${ const { x = "q"; }}''
diff --git a/tests/lexer.sh b/tests/lexer.sh
new file mode 100644
index 000000000000..e45a6b00a542
--- /dev/null
+++ b/tests/lexer.sh
@@ -0,0 +1,3 @@
+source common.sh
+
+nix-instantiate --eval ./lexer.nix
diff --git a/tests/local.mk b/tests/local.mk
index 03f53b44c275..05c6e04ee17e 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -11,7 +11,7 @@ nix_tests = \
   binary-patching.sh timeout.sh secure-drv-outputs.sh nix-channel.sh \
   multiple-outputs.sh import-derivation.sh fetchurl.sh optimise-store.sh \
   binary-cache.sh nix-profile.sh repair.sh dump-db.sh case-hack.sh \
-  check-reqs.sh pass-as-file.sh tarball.sh
+  check-reqs.sh pass-as-file.sh tarball.sh lexer.sh
   # parallel.sh
 
 install-tests += $(foreach x, $(nix_tests), tests/$(x))