8 #include "blocks/error.h"
9 #include "swf4compiler.tab.h" /* defines token types */
13 static const char *lexBuffer = NULL;
14 static int lexBufferLen = 0;
16 static int sLineNumber = 0;
17 static char szLine[1024];
18 static char msgbufs[2][1024] = { {0}, {0} }, *msgline = {0};
19 static int column = 0;
21 static void comment();
22 static void comment1();
24 static void warning(char *msg);
26 #define YY_INPUT(buf,result,max_size) result=lexBufferInput(buf, max_size)
28 /* thanks to the prolific and brilliant Raff: */
29 static int lexBufferInput(char *buf, int max_size)
31 int l = lexBufferLen > max_size ? max_size : lexBufferLen;
33 if (lexBufferLen <= 0)
36 memcpy(buf, lexBuffer, l);
42 /* very inefficient method of unescaping strings */
43 static void unescape(char *buf)
47 for (p1=buf; (p=strchr(p1, '\\')) != 0; p1 = p+1) {
50 case 'b' : p[1] = '\b'; break;
51 case 'f' : p[1] = '\f'; break;
52 case 'n' : p[1] = '\n'; break;
53 case 'r' : p[1] = '\r'; break;
54 case 't' : p[1] = '\t'; break;
56 case 'u' : warning("unsupported escape sequence");
62 void swf4ParseInit(const char *script, int debug)
70 lexBufferLen = strlen(script);
79 // forward declaration needed by the following function
82 #define YY_PROTO(proto) proto
84 #define YY_PROTO(proto) ()
87 static void yyunput YY_PROTO(( int c, char *buf_ptr ));
89 void do_unput4(const char c) { unput(c); }
93 ID [a-zA-Z_][a-zA-Z0-9_]*
98 {DIGIT}+ { count(); swf4lval.str = strdup(yytext);
100 {DIGIT}+"."{DIGIT}* { count(); swf4lval.str = strdup(yytext);
102 true { count(); swf4lval.str = strdup("1");
104 false { count(); swf4lval.str = strdup("0");
106 break { count(); return BREAK; }
107 continue { count(); return CONTINUE; }
108 else { count(); return ELSE; }
109 for { count(); return FOR; }
110 if { count(); return IF; }
111 while { count(); return WHILE; }
112 do { count(); return DO; }
113 valueOf { count(); return EVAL; }
116 random { count(); return RANDOM; }
117 time { count(); return TIME; }
118 length { count(); return LENGTH; }
119 int { count(); return INT; }
120 concat { count(); return CONCAT; }
121 duplicateClip { count(); return DUPLICATECLIP; }
122 removeClip { count(); return REMOVECLIP; }
123 trace { count(); return TRACE; }
124 startDrag { count(); return STARTDRAG; }
125 stopDrag { count(); return STOPDRAG; }
126 ord { count(); return ORD; }
127 chr { count(); return CHR; }
128 callFrame { count(); return CALLFRAME; }
129 getURL { count(); return GETURL; }
130 getURL1 { count(); return GETURL1; }
131 loadMovie { count(); return LOADMOVIE; }
132 loadVariables { count(); return LOADVARIABLES; }
133 substr { count(); return SUBSTR; }
135 getProperty { count(); return GETPROPERTY; }
137 /* getURL2 methods */
138 post { count(); swf4lval.getURLMethod = GETURL_METHOD_POST;
139 return GETURL_METHOD; }
140 get { count(); swf4lval.getURLMethod = GETURL_METHOD_GET;
141 return GETURL_METHOD; }
142 nosend { count(); swf4lval.getURLMethod = GETURL_METHOD_NOSEND;
143 return GETURL_METHOD; }
147 nextFrame { count(); return NEXTFRAME; }
148 prevFrame { count(); return PREVFRAME; }
149 play { count(); return PLAY; }
150 stop { count(); return STOP; }
151 toggleQuality { count(); return TOGGLEQUALITY; }
152 stopSounds { count(); return STOPSOUNDS; }
153 gotoFrame { count(); return GOTOFRAME; }
154 gotoAndPlay { count(); return GOTOANDPLAY; }
155 frameLoaded { count(); return FRAMELOADED; }
156 setTarget { count(); return SETTARGET; }
158 /* high level functions */
159 tellTarget { count(); return TELLTARGET; }
162 this { count(); return THIS; }
164 {ID} { count(); swf4lval.str = strdup(yytext);
167 {LEVEL}?("/"({ID}|{LEVEL}))+ { count(); swf4lval.str = strdup(yytext);
170 {ID}("/"({ID}|{LEVEL}))+ { count(); swf4lval.str = strdup(yytext);
173 \"(\\.|[^\\"])*\" { count(); swf4lval.str = strdup(yytext+1);
174 swf4lval.str[strlen(swf4lval.str)-1]=0;
175 unescape(swf4lval.str);
178 \'(\\.|[^\\'])*\' { count(); swf4lval.str = strdup(yytext+1);
179 swf4lval.str[strlen(swf4lval.str)-1]=0;
180 unescape(swf4lval.str);
183 \"(\\.|[^\\"])*$ { count(); swf4lval.str = strdup("");
184 warning("Unterminated string!");
187 \'(\\.|[^\\'])*$ { count(); swf4lval.str = strdup("");
188 warning("Unterminated string!");
191 "/*" { count(); comment(); }
192 "//" { count(); comment1(); }
193 [ \t\v\f] { count(); }
195 "++" { count(); return INC; }
196 "--" { count(); return DEC; }
197 "<" { count(); return '<'; }
198 ">" { count(); return '>'; }
199 "<=" { count(); return LE; }
200 ">=" { count(); return GE; }
201 "==" { count(); return EQ; }
202 "!=" { count(); return NE; }
203 "&&" { count(); return LAN; }
204 "||" { count(); return LOR; }
205 "*=" { count(); return MEQ; }
206 "/=" { count(); return DEQ; }
207 "+=" { count(); return IEQ; }
208 "-=" { count(); return SEQ; }
209 "===" { count(); return STREQ; }
210 "!==" { count(); return STRNE; }
211 "<=>" { count(); return STRCMP; }
212 ".." { count(); return PARENT; }
214 ";" { count(); return ';'; }
215 "=" { count(); return '='; }
216 "+" { count(); return '+'; }
217 "-" { count(); return '-'; }
218 "&" { count(); return '&'; }
219 "*" { count(); return '*'; }
220 "/" { count(); return '/'; }
221 "!" { count(); return '!'; }
222 "(" { count(); return '('; }
223 ")" { count(); return ')'; }
224 "[" { count(); return '['; }
225 "]" { count(); return ']'; }
226 "{" { count(); return '{'; }
227 "}" { count(); return '}'; }
228 "," { count(); return ','; }
229 "." { count(); return '.'; }
230 "?" { count(); return '?'; }
231 ":" { count(); return ':'; }
233 \r?\n { count(); column = 0;
234 strcpy(szLine, yytext + 1);
235 ++sLineNumber; yyless(1); }
237 . printf( "Unrecognized character: %s\n", yytext );
240 static int getinput() {
253 static void countline()
260 msgline = msgbufs[sLineNumber & 1];
263 static int LineNumber(void)
265 return (sLineNumber + 1);
268 static int ColumnNumber(void)
273 static char *LineText(void)
279 static void comment(void)
281 // Handle block comments
286 // We have the start of a comment so look skip everything up to the
287 // end of the comment character
288 while ((c = getinput()) != '*' && c != EOF)
295 // keep the line number in synch
298 // start the output (matches the algorithim in the lexx above)
302 if (swf4debug) putchar(c);
305 // is this the end of comment character
306 if ((c1 = getinput()) != '/' && c != EOF)
308 // false start as this was no end of comment
313 // write out the start of the end of comment
315 if (swf4debug) putchar(c);
317 // write out the end of the end of comment
319 if (swf4debug) putchar(c1);
322 static void comment1(void)
324 // Handle comment of type 1 (ie '//')
328 // this is a line comment
329 while ((c = getinput()) != '\n' && c != EOF)
331 if (swf4debug) putchar(c);
339 // keep the line number in synch
342 if (swf4debug) putchar(c);
348 static void count(void)
352 // Count the characters to maintain the current column position
353 if (yytext[0] == '\n')
355 if (swf4debug) printf("\n");
359 if (swf4debug) printf("%s", yytext);
361 for(n=0; n<yyleng; ++n, ++column)
364 msgline[column] = yytext[n];
367 //-- keep writing the stuff to standard output
372 static void printprog()
375 SWF_warn("\n%s", msgbufs[(sLineNumber-1)&1]);
380 SWF_warn("\n%s", msgline);
383 static void warning(char *msg)
385 // print a warning message
387 SWF_warn("\n%*s", ColumnNumber(), "^");
388 SWF_warn("\nLine %4.4d: Reason: '%s' \n", LineNumber(), msg);
391 void swf4error(char *msg)
396 SWF_error("\n%s\n%*s\nLine %i: Reason: '%s'\n",
397 LineText(), ColumnNumber(), "^", LineNumber(), msg);
401 SWF_error("\nLine %d: Reason: 'Unexpected EOF found while looking for input.'\n", LineNumber());