--- l2_spec_scan.l 2001/11/08 09:33:37 1.4
+++ l2_spec_scan.l 2001/11/08 21:58:00 1.5
@@ -46,68 +46,98 @@
/* scanner options */
%pointer
+%option stack
%option reentrant-bison
%option never-interactive
%option noyywrap
/* scanner states */
-%x str
+%x SS_PARAM
+%x SS_PARAM_Q
%%
/* local variables */
- char caStr[2048];
- char *cpStr = NULL;
+ char caParam[2048];
+ char *cpParam = NULL;
- /* whitespaces */
-[ \t\n]+ {
- /* NOOP */
+ /* parameter value */
+<SS_PARAM>\" {
+ if (cpParam == NULL)
+ cpParam = caParam;
+ BEGIN(SS_PARAM_Q);
+}
+<SS_PARAM>\\. {
+ if (cpParam == NULL)
+ cpParam = caParam;
+ *cpParam++ = yytext[1];
}
-
- /* C-style strings ("...") */
-\" {
- cpStr = caStr;
- BEGIN(str);
-}
-<str>\" {
- BEGIN(INITIAL);
- *cpStr = '\0';
- yylval->cpValue = strdup(caStr);
- return T_STRING;
-}
-<str>\n {
+<SS_PARAM>[^ \t\r\n\\,)"]+ {
+ char *cp = yytext;
+ if (cpParam == NULL)
+ cpParam = caParam;
+ while (*cp != '\0')
+ *cpParam++ = *cp++;
+}
+<SS_PARAM>(.|\n) {
+ if (cpParam == NULL)
+ cpParam = caParam;
+ *cpParam = '\0';
+ yylval->cpValue = strdup(caParam);
+ cpParam = NULL;
+ yyless(0);
+ return T_PARAM;
+}
+<SS_PARAM_Q>\" {
+ BEGIN(SS_PARAM);
+}
+<SS_PARAM_Q>\n {
l2_env_errorinfo(CTX->env, L2_ERR_ARG, "%s", "Unterminated string");
CTX->rv = L2_ERR_ARG;
+ return 0;
}
-<str>\\[0-7]{1,3} {
+<SS_PARAM_Q>\\[0-7]{1,3} {
unsigned int result;
(void)sscanf(yytext+1, "%o", &result);
if (result > 0xff) {
l2_env_errorinfo(CTX->env, L2_ERR_ARG, "%s", "Escape sequence out of bound");
CTX->rv = L2_ERR_ARG;
+ return 0;
}
else
- *cpStr++ = result;
+ *cpParam++ = result;
}
-<str>\\[0-9]+ {
- l2_env_errorinfo(CTX->env, L2_ERR_ARG, "%s", "Bad escape sequence");
- CTX->rv = L2_ERR_ARG;
+<SS_PARAM_Q>\\x[0-9a-fA-F]{2} {
+ unsigned int result;
+ (void)sscanf(yytext+1, "%x", &result);
+ if (result > 0xff) {
+ l2_env_errorinfo(CTX->env, L2_ERR_ARG, "%s", "Escape sequence out of bound");
+ CTX->rv = L2_ERR_ARG;
+ return 0;
+ }
+ else
+ *cpParam++ = result;
}
-<str>\\n { *cpStr++ = '\n'; }
-<str>\\r { *cpStr++ = '\r'; }
-<str>\\t { *cpStr++ = '\t'; }
-<str>\\b { *cpStr++ = '\b'; }
-<str>\\f { *cpStr++ = '\f'; }
-<str>\\(.|\n) {
- *cpStr++ = yytext[1];
+<SS_PARAM_Q>\\n { *cpParam++ = '\n'; }
+<SS_PARAM_Q>\\r { *cpParam++ = '\r'; }
+<SS_PARAM_Q>\\t { *cpParam++ = '\t'; }
+<SS_PARAM_Q>\\b { *cpParam++ = '\b'; }
+<SS_PARAM_Q>\\f { *cpParam++ = '\f'; }
+<SS_PARAM_Q>\\(.|\n) {
+ *cpParam++ = yytext[1];
}
-<str>[^\\\n\"]+ {
+<SS_PARAM_Q>[^\\\"]+ {
char *cp = yytext;
while (*cp != '\0')
- *cpStr++ = *cp++;
+ *cpParam++ = *cp++;
+}
+<SS_PARAM_Q>(.|\n) {
+ *cpParam++ = yytext[0];
}
-<str>. {
- *cpStr++ = yytext[1];
+
+ /* whitespaces */
+[ \t\n]+ {
+ /* NOOP */
}
/* operators */
@@ -128,6 +158,19 @@
%%
+/* external scanner state transitions */
+void l2_spec_scan_push(l2_spec_ctx_t *ctx, const char *state);
+void l2_spec_scan_push(l2_spec_ctx_t *ctx, const char *state)
+{
+ if (strcmp(state, "SS_PARAM") == 0)
+ yy_push_state(SS_PARAM, ctx->yyscan);
+}
+void l2_spec_scan_pop(l2_spec_ctx_t *ctx);
+void l2_spec_scan_pop(l2_spec_ctx_t *ctx)
+{
+ yy_pop_state(ctx->yyscan);
+}
+
/* buffer-based input routine */
static int yyinput(l2_spec_ctx_t *ctx, char *buf, int max_size)
{
|