From 0064599a27ec44880e4ff6fa19f453e610b5ef07 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 May 2006 14:01:47 +0000 Subject: * String interpolation. Expressions like "--with-freetype2-library=" + freetype + "/lib" can now be written as "--with-freetype2-library=${freetype}/lib" An arbitrary expression can be enclosed within ${...}, not just identifiers. * Escaping in string literals: \n, \r, \t interpreted as in C, any other character following \ is interpreted as-is. * Newlines are now allowed in string literals. --- src/libexpr/lexer.l | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'src/libexpr/lexer.l') diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l index d5a14f517acc..47f2bca1e699 100644 --- a/src/libexpr/lexer.l +++ b/src/libexpr/lexer.l @@ -3,6 +3,9 @@ %option never-interactive +%x STRING + + %{ #include #include @@ -28,6 +31,9 @@ static void adjustLoc(YYLTYPE * loc, const char * s, size_t len) } } +ATerm toATerm(const char * s); +ATerm unescapeStr(const char * s); + #define YY_USER_INIT initLoc(yylloc) #define YY_USER_ACTION adjustLoc(yylloc, yytext, yyleng); @@ -36,7 +42,6 @@ static void adjustLoc(YYLTYPE * loc, const char * s, size_t len) ID [a-zA-Z\_][a-zA-Z0-9\_\']* INT [0-9]+ -STR \"[^\n\"]*\" PATH [a-zA-Z0-9\.\_\-\+]*(\/[a-zA-Z0-9\.\_\-\+]+)+ URI [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']+ @@ -61,19 +66,27 @@ inherit { return INHERIT; } \/\/ { return UPDATE; } \+\+ { return CONCAT; } -{ID} { yylval->t = ATmake("", yytext); return ID; /* !!! alloc */ } +{ID} { yylval->t = toATerm(yytext); return ID; /* !!! alloc */ } {INT} { int n = atoi(yytext); /* !!! overflow */ yylval->t = ATmake("", n); return INT; } -{STR} { int len = strlen(yytext); - yytext[len - 1] = 0; - yylval->t = ATmake("", yytext + 1); - yytext[len - 1] = '\"'; - return STR; /* !!! alloc */ + +\" { BEGIN(STRING); return '"'; } +([^\$\"\\]|\\.|\$[^\{\$])+ { +/* Note: a dollar *is* allowed as-is in a string, as long as it's + not followed by a open brace. This should probably be disallowed + eventually. */ + yylval->t = unescapeStr(yytext); /* !!! alloc */ + return STR; } -{PATH} { yylval->t = ATmake("", yytext); return PATH; /* !!! alloc */ } -{URI} { yylval->t = ATmake("", yytext); return URI; /* !!! alloc */ } +\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; } +\" { BEGIN(INITIAL); return '"'; } +. return yytext[0]; /* just in case: shouldn't be reached */ + + +{PATH} { yylval->t = toATerm(yytext); return PATH; /* !!! alloc */ } +{URI} { yylval->t = toATerm(yytext); return URI; /* !!! alloc */ } [ \t\n]+ /* eat up whitespace */ \#[^\n]* /* single-line comments */ @@ -83,3 +96,13 @@ inherit { return INHERIT; } %% + +/* 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); +} -- cgit 1.4.1