4 MPSL - Minimum Profit Scripting Language
5 Copyright (C) 2003/2010 Angel Ortega <angel@triptico.com>
7 mpsl.l - Minimum Profit Scripting Language [F]lexer
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 http://www.triptico.com
34 void yyerror(char * s);
35 int yy_input_for_flex(char * buf, int max);
37 /* redefinition of input function for GNU Flex */
39 #define YY_INPUT(b,r,m) (r = yy_input_for_flex(b,m))
41 /* internal pointer to next character in code */
42 wchar_t *mpsl_next_char = NULL;
44 /* file stream for compiling from file */
45 FILE *mpsl_file = NULL;
50 /* cached value MPSL.LC */
51 mpdm_t mpsl_lc = NULL;
53 /* dynamic string manipulation macros */
55 struct ds { wchar_t * d; int p; int s; };
56 #define ds_init(x) do { x.d = (wchar_t *)0; x.p = x.s = 0; } while(0)
57 #define ds_rewind(x) x.p = 0;
58 #define ds_free(x) do { if(x.d) free(x.d); ds_init(x); } while(0)
59 #define ds_redim(x) do { if(x.p >= x.s) x.d = realloc(x.d, ++x.s * sizeof(wchar_t)); } while(0)
60 #define ds_poke(x,c) do { ds_redim(x); x.d[x.p++] = c; } while(0)
61 #define ds_pokes(x,t) do { wchar_t *p = t; while(*p) ds_poke(x, *p++); } while(0)
64 /* a dynamic string */
67 static wchar_t *s_mbstowcs(char *str)
68 /* converts from mbs to wcs, using a static buffer */
70 static wchar_t * wc = NULL;
74 /* allocs wchar_t space, if needed */
75 if ((n = mbstowcs(NULL, str, 0)) > wc_s) {
77 wc = realloc(wc, (wc_s + 1) * sizeof(wchar_t));
88 static mpdm_t literal_cache(char *ptr, wchar_t *wptr)
89 /* the cache of literal values */
93 /* convert to wchar_t */
95 wptr = s_mbstowcs(ptr);
98 if ((v = mpdm_hget_s(mpsl_lc, wptr)) == NULL) {
100 mpdm_hset(mpsl_lc, v, v);
115 HEXQUAD {HEXDIGIT}{1,4}
118 OCTINTEGER 0{OCTDIGIT}+
119 HEXINTEGER 0[xX]{HEXDIGIT}+
120 BININTEGER 0[bB]{BINDIGIT}+
122 REAL {DIGIT}*[\.]?{DIGIT}+
123 SCIENT {DIGIT}+(\.{DIGIT}+)?[eE][-+]?{DIGIT}+
124 SYMBOL {LETTER}({LETTER}|{DIGIT})*
125 INTEGER ({DECINTEGER}|{OCTINTEGER}|{HEXINTEGER}|{BININTEGER})
134 yylval.v = literal_cache(yytext, NULL);
140 yylval.v = literal_cache(yytext, NULL);
145 /* single quoted string; return as is */
146 yytext[yyleng - 1] = '\0';
147 yylval.v = literal_cache(yytext + 1, NULL);
152 "while" return WHILE;
156 "foreach" return FOREACH;
157 "local" return LOCAL;
158 "break" return BREAK;
159 "return" return RETURN;
167 "=>" return HASHPAIR;
197 yylval.v = literal_cache(yytext, NULL);
201 {WSPACE} ; /* ignore spaces */
205 \/\* { BEGIN REM; /* C-like comments */ }
206 <REM>\*\/ { BEGIN 0; }
207 <REM>\n { mpsl_line++; }
210 \" { BEGIN STR; ds_rewind(ds_v); }
211 <STR>\n { ds_poke(ds_v, L'\n'); mpsl_line++; }
212 <STR>\\n { ds_poke(ds_v, L'\n'); }
213 <STR>\\t { ds_poke(ds_v, L'\t'); }
214 <STR>\\r { ds_poke(ds_v, L'\r'); }
215 <STR>\\e { ds_poke(ds_v, 27); }
216 <STR>\\\" { ds_poke(ds_v, L'\"'); }
217 <STR>\\\\ { ds_poke(ds_v, L'\\'); }
218 <STR>\"\\\n[ \t]+\" ;
220 ds_poke(ds_v, L'\0');
221 yylval.v = literal_cache(NULL, ds_v.d);
225 <STR>\\x\{{HEXQUAD}\} {
228 sscanf(yytext, "\\x{%x}", &c);
229 ds_poke(ds_v, (wchar_t) c);
231 <STR>. { wchar_t wc; if (mbtowc(&wc, yytext, 1) > 0) ds_poke(ds_v, wc); }
233 . { return *yytext; }
237 int yywrap(void) { return 1; }
239 int yy_input_for_flex(char *buf, int max)
243 if (mpsl_file != NULL) {
247 if ((c = fgetc(mpsl_file)) == EOF) {
256 if (mpsl_next_char != NULL) {
258 char tmp[64]; /* really MB_CUR_MAX + 1 */
261 if (*mpsl_next_char == L'\0' ||
262 (c = wctomb(tmp, *mpsl_next_char)) < 0) {
263 mpsl_next_char = NULL;
267 /* no room? try next time */
274 for (i = 0; i < c; i++)