aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/lexer.l33
1 files changed, 15 insertions, 18 deletions
diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l
index a052447d3..c34e5c383 100644
--- a/src/libexpr/lexer.l
+++ b/src/libexpr/lexer.l
@@ -6,9 +6,9 @@
%option nounput noyy_top_state
+%s DEFAULT
%x STRING
%x IND_STRING
-%x INSIDE_DOLLAR_CURLY
%{
@@ -99,8 +99,6 @@ URI [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~
%%
-<INITIAL,INSIDE_DOLLAR_CURLY>{
-
if { return IF; }
then { return THEN; }
@@ -140,17 +138,19 @@ or { return OR_KW; }
return FLOAT;
}
-\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; }
-}
+\$\{ { PUSH_STATE(DEFAULT); return DOLLAR_CURLY; }
-\} { return '}'; }
-<INSIDE_DOLLAR_CURLY>\} { POP_STATE(); return '}'; }
-\{ { return '{'; }
-<INSIDE_DOLLAR_CURLY>\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return '{'; }
+\} { /* State INITIAL only exists at the bottom of the stack and is
+ used as a marker. DEFAULT replaces it everywhere else.
+ Popping when in INITIAL state causes an empty stack exception,
+ so don't */
+ if (YYSTATE != INITIAL)
+ POP_STATE();
+ return '}';
+ }
+\{ { PUSH_STATE(DEFAULT); return '{'; }
-<INITIAL,INSIDE_DOLLAR_CURLY>\" {
- PUSH_STATE(STRING); return '"';
- }
+\" { PUSH_STATE(STRING); return '"'; }
<STRING>([^\$\"\\]|\$[^\{\"\\]|\\{ANY}|\$\\{ANY})*\$/\" |
<STRING>([^\$\"\\]|\$[^\{\"\\]|\\{ANY}|\$\\{ANY})+ {
/* It is impossible to match strings ending with '$' with one
@@ -159,7 +159,7 @@ or { return OR_KW; }
yylval->e = unescapeStr(data->symbols, yytext, yyleng);
return STR;
}
-<STRING>\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; }
+<STRING>\$\{ { PUSH_STATE(DEFAULT); return DOLLAR_CURLY; }
<STRING>\" { POP_STATE(); return '"'; }
<STRING>\$|\\|\$\\ {
/* This can only occur when we reach EOF, otherwise the above
@@ -169,7 +169,7 @@ or { return OR_KW; }
return STR;
}
-<INITIAL,INSIDE_DOLLAR_CURLY>\'\'(\ *\n)? { PUSH_STATE(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;
@@ -187,14 +187,13 @@ or { return OR_KW; }
yylval->e = unescapeStr(data->symbols, yytext + 2, yyleng - 2);
return IND_STR;
}
-<IND_STRING>\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; }
+<IND_STRING>\$\{ { PUSH_STATE(DEFAULT); return DOLLAR_CURLY; }
<IND_STRING>\'\' { POP_STATE(); return IND_STRING_CLOSE; }
<IND_STRING>\' {
yylval->e = new ExprIndStr("'");
return IND_STR;
}
-<INITIAL,INSIDE_DOLLAR_CURLY>{
{PATH} { if (yytext[yyleng-1] == '/')
throw ParseError("path '%s' has a trailing slash", yytext);
@@ -219,7 +218,5 @@ or { return OR_KW; }
return (unsigned char) yytext[0];
}
-}
-
%%