/* Prologue (directives). -*- C -*- */ /* Disable Flex features we don't need, to avoid warnings. */ %option nodefault noinput nounput noyywrap %option reentrant %{ #include #include /* INT_MIN */ #include /* strtol */ #include "parse.h" %} %x SC_STRING %% %{ // Number of opened parentheses. int nesting = 0; // A buffer storing the text inside the outer parentheses. char *str = NULL; // Its allocated size. int capacity = 0; // Its used size. int size = 0; #define STR_APPEND() \ do { \ if (capacity < size + yyleng + 1) \ { \ do \ capacity = capacity ? 2 * capacity : 128; \ while (capacity < size + yyleng + 1); \ str = realloc (str, capacity); \ } \ memcpy (str + size, yytext, yyleng); \ size += yyleng; \ assert (size < capacity); \ } while (0) %} // Rules. "+" return TOK_PLUS; "-" return TOK_MINUS; "*" return TOK_STAR; "/" return TOK_SLASH; "(" nesting += 1; BEGIN SC_STRING; /* Scan an integer. */ [0-9]+ { errno = 0; long n = strtol (yytext, NULL, 10); if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE)) yyerror (yyscanner, res, "integer is out of range"); yylval->TOK_NUM = (int) n; return TOK_NUM; } /* Ignore white spaces. */ [ \t]+ continue; "\n" return TOK_EOL; . yyerror (yyscanner, res, "syntax error, invalid character: %c", yytext[0]); { "("+ nesting += yyleng; STR_APPEND (); ")" { if (!--nesting) { BEGIN INITIAL; if (str) str[size] = 0; yylval->TOK_STR = str; return TOK_STR; } else STR_APPEND (); } [^()]+ STR_APPEND (); } <> return TOK_EOF; %% /* Epilogue (C code). */