13ae02089SMasatake YAMATO /*
23ae02089SMasatake YAMATO * Copyright (c) 2008, David Fishburn
33ae02089SMasatake YAMATO *
43ae02089SMasatake YAMATO * This source code is released for free distribution under the terms of the
50ce38835Sviccuad * GNU General Public License version 2 or (at your option) any later version.
63ae02089SMasatake YAMATO *
73ae02089SMasatake YAMATO * This module contains functions for generating tags for Adobe languages.
83ae02089SMasatake YAMATO * There are a number of different ones, but this will begin with:
93ae02089SMasatake YAMATO * Flex
103ae02089SMasatake YAMATO * MXML files (*.mMacromedia XML)
113ae02089SMasatake YAMATO * ActionScript files (*.as)
123ae02089SMasatake YAMATO *
138bbb9d0dSColomban Wendling * The ActionScript code was copied from the JavaScript parser, with some
148bbb9d0dSColomban Wendling * adaptations e.g. for classes and type specifiers.
158bbb9d0dSColomban Wendling *
163ae02089SMasatake YAMATO * Flex 3 language reference
173ae02089SMasatake YAMATO * http://livedocs.adobe.com/flex/3/langref/index.html
188bbb9d0dSColomban Wendling * https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/language-elements.html
197495a06bSColomban Wendling * https://www.adobe.com/devnet/actionscript/learning/as3-fundamentals/packages.html
203ae02089SMasatake YAMATO */
213ae02089SMasatake YAMATO
223ae02089SMasatake YAMATO /*
233ae02089SMasatake YAMATO * INCLUDE FILES
243ae02089SMasatake YAMATO */
253ae02089SMasatake YAMATO #include "general.h" /* must always come first */
263ae02089SMasatake YAMATO #include <ctype.h> /* to define isalpha () */
273ae02089SMasatake YAMATO #ifdef DEBUG
283ae02089SMasatake YAMATO #include <stdio.h>
293ae02089SMasatake YAMATO #endif
303ae02089SMasatake YAMATO
313ae02089SMasatake YAMATO #include "debug.h"
323ae02089SMasatake YAMATO #include "entry.h"
333ae02089SMasatake YAMATO #include "keyword.h"
343ae02089SMasatake YAMATO #include "parse.h"
353ae02089SMasatake YAMATO #include "read.h"
363ae02089SMasatake YAMATO #include "routines.h"
373ae02089SMasatake YAMATO #include "vstring.h"
388bbb9d0dSColomban Wendling #include "strlist.h"
393ae02089SMasatake YAMATO
403ae02089SMasatake YAMATO /*
413ae02089SMasatake YAMATO * MACROS
423ae02089SMasatake YAMATO */
43ce990805SThomas Braun #define isType(token,t) (bool) ((token)->type == (t))
44ce990805SThomas Braun #define isKeyword(token,k) (bool) ((token)->keyword == (k))
452b28d0e0SJiří Techet #define isEOF(token) (isType ((token), TOKEN_EOF))
462b28d0e0SJiří Techet #define isIdentChar(c) \
472b28d0e0SJiří Techet (isalpha (c) || isdigit (c) || (c) == '$' || \
488bbb9d0dSColomban Wendling (c) == '@' || (c) == '_' || (c) == '#' || \
498bbb9d0dSColomban Wendling (c) >= 0x80)
503ae02089SMasatake YAMATO
513ae02089SMasatake YAMATO /*
523ae02089SMasatake YAMATO * DATA DECLARATIONS
533ae02089SMasatake YAMATO */
543ae02089SMasatake YAMATO
553ae02089SMasatake YAMATO /*
563ae02089SMasatake YAMATO * Tracks class and function names already created
573ae02089SMasatake YAMATO */
583ae02089SMasatake YAMATO static stringList *ClassNames;
593ae02089SMasatake YAMATO static stringList *FunctionNames;
603ae02089SMasatake YAMATO
613ae02089SMasatake YAMATO /* Used to specify type of keyword.
623ae02089SMasatake YAMATO */
634faa2076SColomban Wendling enum eKeywordId {
643ae02089SMasatake YAMATO KEYWORD_function,
653ae02089SMasatake YAMATO KEYWORD_capital_function,
663ae02089SMasatake YAMATO KEYWORD_object,
673ae02089SMasatake YAMATO KEYWORD_capital_object,
683ae02089SMasatake YAMATO KEYWORD_prototype,
693ae02089SMasatake YAMATO KEYWORD_var,
7024528e6eSColomban Wendling KEYWORD_const,
713ae02089SMasatake YAMATO KEYWORD_new,
723ae02089SMasatake YAMATO KEYWORD_this,
733ae02089SMasatake YAMATO KEYWORD_for,
743ae02089SMasatake YAMATO KEYWORD_while,
753ae02089SMasatake YAMATO KEYWORD_do,
763ae02089SMasatake YAMATO KEYWORD_if,
773ae02089SMasatake YAMATO KEYWORD_else,
783ae02089SMasatake YAMATO KEYWORD_switch,
793ae02089SMasatake YAMATO KEYWORD_try,
803ae02089SMasatake YAMATO KEYWORD_catch,
813ae02089SMasatake YAMATO KEYWORD_finally,
828bbb9d0dSColomban Wendling KEYWORD_return,
833ae02089SMasatake YAMATO KEYWORD_public,
843ae02089SMasatake YAMATO KEYWORD_private,
856544ac44SColomban Wendling KEYWORD_protected,
866544ac44SColomban Wendling KEYWORD_internal,
876544ac44SColomban Wendling KEYWORD_final,
886544ac44SColomban Wendling KEYWORD_native,
89ba44ff41SColomban Wendling KEYWORD_dynamic,
903ae02089SMasatake YAMATO KEYWORD_class,
91c8580ab1SColomban Wendling KEYWORD_interface,
923a43a456SColomban Wendling KEYWORD_package,
93bf149776SColomban Wendling KEYWORD_extends,
948bbb9d0dSColomban Wendling KEYWORD_static,
95bf149776SColomban Wendling KEYWORD_implements,
96644209f6SColomban Wendling KEYWORD_get,
97644209f6SColomban Wendling KEYWORD_set,
9822848dcdSColomban Wendling KEYWORD_import,
993ae02089SMasatake YAMATO KEYWORD_id,
1003ae02089SMasatake YAMATO KEYWORD_name,
1013ae02089SMasatake YAMATO KEYWORD_script,
1023ae02089SMasatake YAMATO KEYWORD_cdata,
1033ae02089SMasatake YAMATO KEYWORD_mx,
1043ae02089SMasatake YAMATO KEYWORD_fx,
1053ae02089SMasatake YAMATO KEYWORD_override
1064faa2076SColomban Wendling };
1074faa2076SColomban Wendling typedef int keywordId; /* to allow KEYWORD_NONE */
1083ae02089SMasatake YAMATO
1093ae02089SMasatake YAMATO typedef enum eTokenType {
1103ae02089SMasatake YAMATO TOKEN_UNDEFINED,
11117d3d2f0SMasatake YAMATO TOKEN_EOF,
1123ae02089SMasatake YAMATO TOKEN_CHARACTER,
1133ae02089SMasatake YAMATO TOKEN_CLOSE_PAREN,
1143ae02089SMasatake YAMATO TOKEN_SEMICOLON,
1153ae02089SMasatake YAMATO TOKEN_COLON,
1163ae02089SMasatake YAMATO TOKEN_COMMA,
1173ae02089SMasatake YAMATO TOKEN_KEYWORD,
1183ae02089SMasatake YAMATO TOKEN_OPEN_PAREN,
1193ae02089SMasatake YAMATO TOKEN_IDENTIFIER,
1203ae02089SMasatake YAMATO TOKEN_STRING,
1213ae02089SMasatake YAMATO TOKEN_PERIOD,
1223ae02089SMasatake YAMATO TOKEN_OPEN_CURLY,
1233ae02089SMasatake YAMATO TOKEN_CLOSE_CURLY,
1243ae02089SMasatake YAMATO TOKEN_EQUAL_SIGN,
1253ae02089SMasatake YAMATO TOKEN_EXCLAMATION,
1263ae02089SMasatake YAMATO TOKEN_FORWARD_SLASH,
1273ae02089SMasatake YAMATO TOKEN_OPEN_SQUARE,
1283ae02089SMasatake YAMATO TOKEN_CLOSE_SQUARE,
1293ae02089SMasatake YAMATO TOKEN_OPEN_MXML,
1303ae02089SMasatake YAMATO TOKEN_CLOSE_MXML,
1313ae02089SMasatake YAMATO TOKEN_CLOSE_SGML,
1323ae02089SMasatake YAMATO TOKEN_LESS_THAN,
1333ae02089SMasatake YAMATO TOKEN_GREATER_THAN,
1343ae02089SMasatake YAMATO TOKEN_QUESTION_MARK,
1358bbb9d0dSColomban Wendling TOKEN_OPEN_NAMESPACE,
1368bbb9d0dSColomban Wendling TOKEN_POSTFIX_OPERATOR,
13722848dcdSColomban Wendling TOKEN_STAR,
1388bbb9d0dSColomban Wendling TOKEN_BINARY_OPERATOR
1393ae02089SMasatake YAMATO } tokenType;
1403ae02089SMasatake YAMATO
1413ae02089SMasatake YAMATO typedef struct sTokenInfo {
1423ae02089SMasatake YAMATO tokenType type;
1433ae02089SMasatake YAMATO keywordId keyword;
1443ae02089SMasatake YAMATO vString * string;
1453ae02089SMasatake YAMATO vString * scope;
1463ae02089SMasatake YAMATO unsigned long lineNumber;
147509a47dbSJiří Techet MIOPos filePosition;
1483ae02089SMasatake YAMATO int nestLevel;
149ce990805SThomas Braun bool ignoreTag;
150ce990805SThomas Braun bool isClass;
1513ae02089SMasatake YAMATO } tokenInfo;
1523ae02089SMasatake YAMATO
1533ae02089SMasatake YAMATO /*
1543ae02089SMasatake YAMATO * DATA DEFINITIONS
1553ae02089SMasatake YAMATO */
1568bbb9d0dSColomban Wendling static tokenType LastTokenType;
1578bbb9d0dSColomban Wendling static tokenInfo *NextToken;
1583ae02089SMasatake YAMATO
159970f6116SJiří Techet static langType Lang_flex;
1603ae02089SMasatake YAMATO
1613ae02089SMasatake YAMATO typedef enum {
1623ae02089SMasatake YAMATO FLEXTAG_FUNCTION,
1633ae02089SMasatake YAMATO FLEXTAG_CLASS,
164c8580ab1SColomban Wendling FLEXTAG_INTERFACE,
1653a43a456SColomban Wendling FLEXTAG_PACKAGE,
1663ae02089SMasatake YAMATO FLEXTAG_METHOD,
1673ae02089SMasatake YAMATO FLEXTAG_PROPERTY,
1683ae02089SMasatake YAMATO FLEXTAG_VARIABLE,
16940ef4438SColomban Wendling FLEXTAG_LOCALVAR,
17024528e6eSColomban Wendling FLEXTAG_CONST,
17122848dcdSColomban Wendling FLEXTAG_IMPORT,
1723ae02089SMasatake YAMATO FLEXTAG_MXTAG,
1733ae02089SMasatake YAMATO FLEXTAG_COUNT
1743ae02089SMasatake YAMATO } flexKind;
1753ae02089SMasatake YAMATO
17622848dcdSColomban Wendling typedef enum {
17722848dcdSColomban Wendling FLEX_IMPORT_ROLE_IMPORTED,
17822848dcdSColomban Wendling } flexImportRole;
17922848dcdSColomban Wendling
18022848dcdSColomban Wendling static roleDefinition FlexImportRoles [] = {
18122848dcdSColomban Wendling { true, "import", "imports" },
18222848dcdSColomban Wendling };
18322848dcdSColomban Wendling
184e112e8abSMasatake YAMATO static kindDefinition FlexKinds [] = {
185ce990805SThomas Braun { true, 'f', "function", "functions" },
186ce990805SThomas Braun { true, 'c', "class", "classes" },
187c8580ab1SColomban Wendling { true, 'i', "interface", "interfaces" },
1883a43a456SColomban Wendling { true, 'P', "package", "packages" },
189ce990805SThomas Braun { true, 'm', "method", "methods" },
190ce990805SThomas Braun { true, 'p', "property", "properties" },
191ce990805SThomas Braun { true, 'v', "variable", "global variables" },
19240ef4438SColomban Wendling { false, 'l', "localvar", "local variables" },
19324528e6eSColomban Wendling { true, 'C', "constant", "constants" },
19422848dcdSColomban Wendling { true, 'I', "import", "imports",
19522848dcdSColomban Wendling .referenceOnly = true, ATTACH_ROLES (FlexImportRoles) },
196ce990805SThomas Braun { true, 'x', "mxtag", "mxtags" }
1973ae02089SMasatake YAMATO };
1983ae02089SMasatake YAMATO
199c379c5d2SMasatake YAMATO /* Used to determine whether keyword is valid for the token language and
200c379c5d2SMasatake YAMATO * what its ID is.
201c379c5d2SMasatake YAMATO */
20282c11d8cSRich Siegel static const keywordTable FlexKeywordTable [] = {
2033ae02089SMasatake YAMATO /* keyword keyword ID */
2043ae02089SMasatake YAMATO { "function", KEYWORD_function },
2053ae02089SMasatake YAMATO { "Function", KEYWORD_capital_function },
2063ae02089SMasatake YAMATO { "object", KEYWORD_object },
2073ae02089SMasatake YAMATO { "Object", KEYWORD_capital_object },
2083ae02089SMasatake YAMATO { "prototype", KEYWORD_prototype },
2093ae02089SMasatake YAMATO { "var", KEYWORD_var },
21024528e6eSColomban Wendling { "const", KEYWORD_const },
2113ae02089SMasatake YAMATO { "new", KEYWORD_new },
2123ae02089SMasatake YAMATO { "this", KEYWORD_this },
2133ae02089SMasatake YAMATO { "for", KEYWORD_for },
2143ae02089SMasatake YAMATO { "while", KEYWORD_while },
2153ae02089SMasatake YAMATO { "do", KEYWORD_do },
2163ae02089SMasatake YAMATO { "if", KEYWORD_if },
2173ae02089SMasatake YAMATO { "else", KEYWORD_else },
2183ae02089SMasatake YAMATO { "switch", KEYWORD_switch },
2193ae02089SMasatake YAMATO { "try", KEYWORD_try },
2203ae02089SMasatake YAMATO { "catch", KEYWORD_catch },
2213ae02089SMasatake YAMATO { "finally", KEYWORD_finally },
2228bbb9d0dSColomban Wendling { "return", KEYWORD_return },
2233ae02089SMasatake YAMATO { "public", KEYWORD_public },
2243ae02089SMasatake YAMATO { "private", KEYWORD_private },
2256544ac44SColomban Wendling { "protected", KEYWORD_protected },
2266544ac44SColomban Wendling { "internal", KEYWORD_internal },
2276544ac44SColomban Wendling { "final", KEYWORD_final },
2286544ac44SColomban Wendling { "native", KEYWORD_native },
229ba44ff41SColomban Wendling { "dynamic", KEYWORD_dynamic },
2303ae02089SMasatake YAMATO { "class", KEYWORD_class },
231c8580ab1SColomban Wendling { "interface", KEYWORD_interface },
2323a43a456SColomban Wendling { "package", KEYWORD_package },
233bf149776SColomban Wendling { "extends", KEYWORD_extends },
2348bbb9d0dSColomban Wendling { "static", KEYWORD_static },
235bf149776SColomban Wendling { "implements", KEYWORD_implements },
236644209f6SColomban Wendling { "get", KEYWORD_get },
237644209f6SColomban Wendling { "set", KEYWORD_set },
23822848dcdSColomban Wendling { "import", KEYWORD_import },
2393ae02089SMasatake YAMATO { "id", KEYWORD_id },
2403ae02089SMasatake YAMATO { "name", KEYWORD_name },
2413ae02089SMasatake YAMATO { "script", KEYWORD_script },
2423ae02089SMasatake YAMATO { "cdata", KEYWORD_cdata },
2433ae02089SMasatake YAMATO { "mx", KEYWORD_mx },
2443ae02089SMasatake YAMATO { "fx", KEYWORD_fx },
2453ae02089SMasatake YAMATO { "override", KEYWORD_override }
2463ae02089SMasatake YAMATO };
2473ae02089SMasatake YAMATO
2483ae02089SMasatake YAMATO /*
2493ae02089SMasatake YAMATO * FUNCTION DEFINITIONS
2503ae02089SMasatake YAMATO */
2513ae02089SMasatake YAMATO
2523ae02089SMasatake YAMATO /* Recursive functions */
2533ae02089SMasatake YAMATO static void parseFunction (tokenInfo *const token);
2548bbb9d0dSColomban Wendling static bool parseBlock (tokenInfo *const token, const vString *const parentScope);
255ce990805SThomas Braun static bool parseLine (tokenInfo *const token);
2569a9998e6SColomban Wendling static bool parseActionScript (tokenInfo *const token, bool readNext);
257ce990805SThomas Braun static bool parseMXML (tokenInfo *const token);
2583ae02089SMasatake YAMATO
newToken(void)2593ae02089SMasatake YAMATO static tokenInfo *newToken (void)
2603ae02089SMasatake YAMATO {
2613ae02089SMasatake YAMATO tokenInfo *const token = xMalloc (1, tokenInfo);
2623ae02089SMasatake YAMATO
2633ae02089SMasatake YAMATO token->type = TOKEN_UNDEFINED;
2643ae02089SMasatake YAMATO token->keyword = KEYWORD_NONE;
2653ae02089SMasatake YAMATO token->string = vStringNew ();
2663ae02089SMasatake YAMATO token->scope = vStringNew ();
2673ae02089SMasatake YAMATO token->nestLevel = 0;
268ce990805SThomas Braun token->isClass = false;
269ce990805SThomas Braun token->ignoreTag = false;
270a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
2713ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
2723ae02089SMasatake YAMATO
2733ae02089SMasatake YAMATO return token;
2743ae02089SMasatake YAMATO }
2753ae02089SMasatake YAMATO
deleteToken(tokenInfo * const token)2763ae02089SMasatake YAMATO static void deleteToken (tokenInfo *const token)
2773ae02089SMasatake YAMATO {
2783ae02089SMasatake YAMATO vStringDelete (token->string);
2793ae02089SMasatake YAMATO vStringDelete (token->scope);
2803ae02089SMasatake YAMATO eFree (token);
2813ae02089SMasatake YAMATO }
2823ae02089SMasatake YAMATO
copyToken(tokenInfo * const dest,tokenInfo * const src,bool const include_non_read_info)2838bbb9d0dSColomban Wendling static void copyToken (tokenInfo *const dest, tokenInfo *const src,
2848bbb9d0dSColomban Wendling bool const include_non_read_info)
2858bbb9d0dSColomban Wendling {
2868bbb9d0dSColomban Wendling dest->lineNumber = src->lineNumber;
2878bbb9d0dSColomban Wendling dest->filePosition = src->filePosition;
2888bbb9d0dSColomban Wendling dest->type = src->type;
2898bbb9d0dSColomban Wendling dest->keyword = src->keyword;
2908bbb9d0dSColomban Wendling dest->isClass = src->isClass;
2918bbb9d0dSColomban Wendling vStringCopy(dest->string, src->string);
2928bbb9d0dSColomban Wendling if (include_non_read_info)
2938bbb9d0dSColomban Wendling {
2948bbb9d0dSColomban Wendling dest->nestLevel = src->nestLevel;
2958bbb9d0dSColomban Wendling vStringCopy(dest->scope, src->scope);
2968bbb9d0dSColomban Wendling }
2978bbb9d0dSColomban Wendling }
2988bbb9d0dSColomban Wendling
2993ae02089SMasatake YAMATO /*
3003ae02089SMasatake YAMATO * Tag generation functions
3013ae02089SMasatake YAMATO */
3023ae02089SMasatake YAMATO
buildQualifiedName(const tokenInfo * const token)303aec4cae6SColomban Wendling static vString *buildQualifiedName (const tokenInfo *const token)
304aec4cae6SColomban Wendling {
305aec4cae6SColomban Wendling vString *qualified = vStringNew ();
306aec4cae6SColomban Wendling
307aec4cae6SColomban Wendling if (vStringLength (token->scope) > 0)
308aec4cae6SColomban Wendling {
309aec4cae6SColomban Wendling vStringCopy (qualified, token->scope);
310aec4cae6SColomban Wendling vStringPut (qualified, '.');
311aec4cae6SColomban Wendling }
312aec4cae6SColomban Wendling vStringCat (qualified, token->string);
313aec4cae6SColomban Wendling
314aec4cae6SColomban Wendling return qualified;
315aec4cae6SColomban Wendling }
316aec4cae6SColomban Wendling
makeConstTag(tokenInfo * const token,const flexKind kind)3173ae02089SMasatake YAMATO static void makeConstTag (tokenInfo *const token, const flexKind kind)
3183ae02089SMasatake YAMATO {
3193ae02089SMasatake YAMATO if (FlexKinds [kind].enabled && ! token->ignoreTag )
3203ae02089SMasatake YAMATO {
3213ae02089SMasatake YAMATO const char *const name = vStringValue (token->string);
3223ae02089SMasatake YAMATO tagEntryInfo e;
323*24b256e3SMasatake YAMATO int role = ROLE_DEFINITION_INDEX;
32422848dcdSColomban Wendling
32522848dcdSColomban Wendling if (kind == FLEXTAG_IMPORT)
32622848dcdSColomban Wendling role = FLEX_IMPORT_ROLE_IMPORTED;
32722848dcdSColomban Wendling
32822848dcdSColomban Wendling initRefTagEntry (&e, name, kind, role);
3293ae02089SMasatake YAMATO
3303ae02089SMasatake YAMATO e.lineNumber = token->lineNumber;
3313ae02089SMasatake YAMATO e.filePosition = token->filePosition;
3323ae02089SMasatake YAMATO
33396b6f8f6SColomban Wendling if ( vStringLength(token->scope) > 0 )
33496b6f8f6SColomban Wendling {
33596b6f8f6SColomban Wendling /* FIXME: proper parent type */
33696b6f8f6SColomban Wendling flexKind parent_kind = FLEXTAG_CLASS;
33796b6f8f6SColomban Wendling
33896b6f8f6SColomban Wendling /*
33996b6f8f6SColomban Wendling * If we're creating a function (and not a method),
34096b6f8f6SColomban Wendling * guess we're inside another function
34196b6f8f6SColomban Wendling */
34296b6f8f6SColomban Wendling if (kind == FLEXTAG_FUNCTION)
34396b6f8f6SColomban Wendling parent_kind = FLEXTAG_FUNCTION;
34496b6f8f6SColomban Wendling /* mxtags can only be nested inside other mxtags */
34596b6f8f6SColomban Wendling else if (kind == FLEXTAG_MXTAG)
34696b6f8f6SColomban Wendling parent_kind = kind;
34796b6f8f6SColomban Wendling
34896b6f8f6SColomban Wendling e.extensionFields.scopeKindIndex = parent_kind;
34996b6f8f6SColomban Wendling e.extensionFields.scopeName = vStringValue (token->scope);
35096b6f8f6SColomban Wendling }
35196b6f8f6SColomban Wendling
3523ae02089SMasatake YAMATO makeTagEntry (&e);
353aec4cae6SColomban Wendling
354aec4cae6SColomban Wendling /* make qualified tags for compatibility if requested */
355aec4cae6SColomban Wendling if (isXtagEnabled (XTAG_QUALIFIED_TAGS))
356aec4cae6SColomban Wendling {
357aec4cae6SColomban Wendling vString *qualified = buildQualifiedName (token);
358aec4cae6SColomban Wendling
359aec4cae6SColomban Wendling markTagExtraBit (&e, XTAG_QUALIFIED_TAGS);
360aec4cae6SColomban Wendling e.name = vStringValue (qualified);
361aec4cae6SColomban Wendling makeTagEntry (&e);
362aec4cae6SColomban Wendling vStringDelete (qualified);
363aec4cae6SColomban Wendling }
3643ae02089SMasatake YAMATO }
3653ae02089SMasatake YAMATO }
3663ae02089SMasatake YAMATO
makeFlexTag(tokenInfo * const token,flexKind kind)3673ae02089SMasatake YAMATO static void makeFlexTag (tokenInfo *const token, flexKind kind)
3683ae02089SMasatake YAMATO {
3693ae02089SMasatake YAMATO if (FlexKinds [kind].enabled && ! token->ignoreTag )
3703ae02089SMasatake YAMATO {
3713ae02089SMasatake YAMATO DebugStatement (
3723ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
3733ae02089SMasatake YAMATO , "\n makeFlexTag start: token isClass:%d scope:%s name:%s\n"
3743ae02089SMasatake YAMATO , token->isClass
3753ae02089SMasatake YAMATO , vStringValue(token->scope)
3763ae02089SMasatake YAMATO , vStringValue(token->string)
3773ae02089SMasatake YAMATO );
3783ae02089SMasatake YAMATO );
3793ae02089SMasatake YAMATO if (kind == FLEXTAG_FUNCTION && token->isClass )
3803ae02089SMasatake YAMATO {
3813ae02089SMasatake YAMATO kind = FLEXTAG_METHOD;
3823ae02089SMasatake YAMATO }
3833ae02089SMasatake YAMATO makeConstTag (token, kind);
3843ae02089SMasatake YAMATO }
3853ae02089SMasatake YAMATO }
3863ae02089SMasatake YAMATO
makeClassTag(tokenInfo * const token)3873ae02089SMasatake YAMATO static void makeClassTag (tokenInfo *const token)
3883ae02089SMasatake YAMATO {
3893ae02089SMasatake YAMATO if ( ! token->ignoreTag )
3903ae02089SMasatake YAMATO {
39156282c12SColomban Wendling vString *fulltag = buildQualifiedName (token);
39256282c12SColomban Wendling
3933ae02089SMasatake YAMATO if ( ! stringListHas(ClassNames, vStringValue (fulltag)) )
3943ae02089SMasatake YAMATO {
3953ae02089SMasatake YAMATO stringListAdd (ClassNames, vStringNewCopy (fulltag));
3963ae02089SMasatake YAMATO makeFlexTag (token, FLEXTAG_CLASS);
3973ae02089SMasatake YAMATO }
3983ae02089SMasatake YAMATO vStringDelete (fulltag);
3993ae02089SMasatake YAMATO }
4003ae02089SMasatake YAMATO }
4013ae02089SMasatake YAMATO
makeMXTag(tokenInfo * const token)4023ae02089SMasatake YAMATO static void makeMXTag (tokenInfo *const token)
4033ae02089SMasatake YAMATO {
4043ae02089SMasatake YAMATO if ( ! token->ignoreTag )
4053ae02089SMasatake YAMATO {
4063ae02089SMasatake YAMATO makeFlexTag (token, FLEXTAG_MXTAG);
4073ae02089SMasatake YAMATO }
4083ae02089SMasatake YAMATO }
4093ae02089SMasatake YAMATO
makeFunctionTag(tokenInfo * const token)4103ae02089SMasatake YAMATO static void makeFunctionTag (tokenInfo *const token)
4113ae02089SMasatake YAMATO {
4123ae02089SMasatake YAMATO if ( ! token->ignoreTag )
4133ae02089SMasatake YAMATO {
41456282c12SColomban Wendling vString *fulltag = buildQualifiedName (token);
41556282c12SColomban Wendling
4163ae02089SMasatake YAMATO if ( ! stringListHas(FunctionNames, vStringValue (fulltag)) )
4173ae02089SMasatake YAMATO {
4183ae02089SMasatake YAMATO stringListAdd (FunctionNames, vStringNewCopy (fulltag));
4193ae02089SMasatake YAMATO makeFlexTag (token, FLEXTAG_FUNCTION);
4203ae02089SMasatake YAMATO }
4213ae02089SMasatake YAMATO vStringDelete (fulltag);
4223ae02089SMasatake YAMATO }
4233ae02089SMasatake YAMATO }
4243ae02089SMasatake YAMATO
4253ae02089SMasatake YAMATO /*
4263ae02089SMasatake YAMATO * Parsing functions
4273ae02089SMasatake YAMATO */
4283ae02089SMasatake YAMATO
parseString(vString * const string,const int delimiter)4293ae02089SMasatake YAMATO static void parseString (vString *const string, const int delimiter)
4303ae02089SMasatake YAMATO {
431ce990805SThomas Braun bool end = false;
4323ae02089SMasatake YAMATO while (! end)
4333ae02089SMasatake YAMATO {
434018bce0bSMasatake YAMATO int c = getcFromInputFile ();
4353ae02089SMasatake YAMATO if (c == EOF)
436ce990805SThomas Braun end = true;
4373ae02089SMasatake YAMATO else if (c == '\\')
4383ae02089SMasatake YAMATO {
439018bce0bSMasatake YAMATO c = getcFromInputFile(); /* This maybe a ' or ". */
4403ae02089SMasatake YAMATO vStringPut(string, c);
4413ae02089SMasatake YAMATO }
4423ae02089SMasatake YAMATO else if (c == delimiter)
443ce990805SThomas Braun end = true;
4443ae02089SMasatake YAMATO else
4453ae02089SMasatake YAMATO vStringPut (string, c);
4463ae02089SMasatake YAMATO }
4473ae02089SMasatake YAMATO }
4483ae02089SMasatake YAMATO
4493ae02089SMasatake YAMATO /* Read a C identifier beginning with "firstChar" and places it into
4503ae02089SMasatake YAMATO * "name".
4513ae02089SMasatake YAMATO */
parseIdentifier(vString * const string,const int firstChar)4523ae02089SMasatake YAMATO static void parseIdentifier (vString *const string, const int firstChar)
4533ae02089SMasatake YAMATO {
4543ae02089SMasatake YAMATO int c = firstChar;
4553ae02089SMasatake YAMATO Assert (isIdentChar (c));
4563ae02089SMasatake YAMATO do
4573ae02089SMasatake YAMATO {
4583ae02089SMasatake YAMATO vStringPut (string, c);
459018bce0bSMasatake YAMATO c = getcFromInputFile ();
4603ae02089SMasatake YAMATO } while (isIdentChar (c));
46161f14fa5SMasatake YAMATO ungetcToInputFile (c); /* unget non-identifier character */
4623ae02089SMasatake YAMATO }
4633ae02089SMasatake YAMATO
readTokenFull(tokenInfo * const token,bool include_newlines)4648bbb9d0dSColomban Wendling static void readTokenFull (tokenInfo *const token, bool include_newlines)
4653ae02089SMasatake YAMATO {
4663ae02089SMasatake YAMATO int c;
4678bbb9d0dSColomban Wendling int i;
4688bbb9d0dSColomban Wendling bool newline_encountered = false;
4698bbb9d0dSColomban Wendling
4708bbb9d0dSColomban Wendling /* if we've got a token held back, emit it */
4718bbb9d0dSColomban Wendling if (NextToken)
4728bbb9d0dSColomban Wendling {
4738bbb9d0dSColomban Wendling copyToken (token, NextToken, false);
4748bbb9d0dSColomban Wendling deleteToken (NextToken);
4758bbb9d0dSColomban Wendling NextToken = NULL;
4768bbb9d0dSColomban Wendling return;
4778bbb9d0dSColomban Wendling }
4783ae02089SMasatake YAMATO
4793ae02089SMasatake YAMATO token->type = TOKEN_UNDEFINED;
4803ae02089SMasatake YAMATO token->keyword = KEYWORD_NONE;
4813ae02089SMasatake YAMATO vStringClear (token->string);
4823ae02089SMasatake YAMATO
4833ae02089SMasatake YAMATO getNextChar:
4848bbb9d0dSColomban Wendling i = 0;
4853ae02089SMasatake YAMATO do
4863ae02089SMasatake YAMATO {
487018bce0bSMasatake YAMATO c = getcFromInputFile ();
4888bbb9d0dSColomban Wendling if (include_newlines && (c == '\r' || c == '\n'))
4898bbb9d0dSColomban Wendling newline_encountered = true;
4908bbb9d0dSColomban Wendling i++;
4918bbb9d0dSColomban Wendling }
4928bbb9d0dSColomban Wendling while (c == '\t' || c == ' ' || c == '\r' || c == '\n');
4938bbb9d0dSColomban Wendling
494a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
4953ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
4963ae02089SMasatake YAMATO
4973ae02089SMasatake YAMATO switch (c)
4983ae02089SMasatake YAMATO {
49917d3d2f0SMasatake YAMATO case EOF: token->type = TOKEN_EOF; break;
5003ae02089SMasatake YAMATO case '(': token->type = TOKEN_OPEN_PAREN; break;
5013ae02089SMasatake YAMATO case ')': token->type = TOKEN_CLOSE_PAREN; break;
5023ae02089SMasatake YAMATO case ';': token->type = TOKEN_SEMICOLON; break;
5033ae02089SMasatake YAMATO case ',': token->type = TOKEN_COMMA; break;
5043ae02089SMasatake YAMATO case '.': token->type = TOKEN_PERIOD; break;
5053ae02089SMasatake YAMATO case ':': token->type = TOKEN_COLON; break;
5063ae02089SMasatake YAMATO case '{': token->type = TOKEN_OPEN_CURLY; break;
5073ae02089SMasatake YAMATO case '}': token->type = TOKEN_CLOSE_CURLY; break;
5083ae02089SMasatake YAMATO case '=': token->type = TOKEN_EQUAL_SIGN; break;
5093ae02089SMasatake YAMATO case '[': token->type = TOKEN_OPEN_SQUARE; break;
5103ae02089SMasatake YAMATO case ']': token->type = TOKEN_CLOSE_SQUARE; break;
5113ae02089SMasatake YAMATO case '?': token->type = TOKEN_QUESTION_MARK; break;
5123ae02089SMasatake YAMATO
5138bbb9d0dSColomban Wendling case '+':
5148bbb9d0dSColomban Wendling case '-':
5158bbb9d0dSColomban Wendling {
5168bbb9d0dSColomban Wendling int d = getcFromInputFile ();
5178bbb9d0dSColomban Wendling if (d == c) /* ++ or -- */
5188bbb9d0dSColomban Wendling token->type = TOKEN_POSTFIX_OPERATOR;
5198bbb9d0dSColomban Wendling else
5208bbb9d0dSColomban Wendling {
5218bbb9d0dSColomban Wendling ungetcToInputFile (d);
5228bbb9d0dSColomban Wendling token->type = TOKEN_BINARY_OPERATOR;
5238bbb9d0dSColomban Wendling }
5248bbb9d0dSColomban Wendling break;
5258bbb9d0dSColomban Wendling }
5268bbb9d0dSColomban Wendling
5278bbb9d0dSColomban Wendling case '*':
52822848dcdSColomban Wendling token->type = TOKEN_STAR;
52922848dcdSColomban Wendling break;
5308bbb9d0dSColomban Wendling case '%':
5318bbb9d0dSColomban Wendling case '^':
5328bbb9d0dSColomban Wendling case '|':
5338bbb9d0dSColomban Wendling case '&':
5348bbb9d0dSColomban Wendling token->type = TOKEN_BINARY_OPERATOR;
5358bbb9d0dSColomban Wendling break;
5368bbb9d0dSColomban Wendling
5373ae02089SMasatake YAMATO case '\'':
5383ae02089SMasatake YAMATO case '"':
5393ae02089SMasatake YAMATO token->type = TOKEN_STRING;
5403ae02089SMasatake YAMATO parseString (token->string, c);
541a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
5423ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
5433ae02089SMasatake YAMATO break;
5443ae02089SMasatake YAMATO
5453ae02089SMasatake YAMATO case '\\':
546018bce0bSMasatake YAMATO c = getcFromInputFile ();
5473ae02089SMasatake YAMATO if (c != '\\' && c != '"' && !isspace (c))
54861f14fa5SMasatake YAMATO ungetcToInputFile (c);
5493ae02089SMasatake YAMATO token->type = TOKEN_CHARACTER;
550a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
5513ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
5523ae02089SMasatake YAMATO break;
5533ae02089SMasatake YAMATO
5543ae02089SMasatake YAMATO case '/':
5553ae02089SMasatake YAMATO {
556018bce0bSMasatake YAMATO int d = getcFromInputFile ();
5573ae02089SMasatake YAMATO if ( (d != '*') && /* is this the start of a comment? */
5583ae02089SMasatake YAMATO (d != '/') && /* is a one line comment? */
5593ae02089SMasatake YAMATO (d != '>') ) /* is this a close XML tag? */
5603ae02089SMasatake YAMATO {
56161f14fa5SMasatake YAMATO ungetcToInputFile (d);
5623ae02089SMasatake YAMATO token->type = TOKEN_FORWARD_SLASH;
563a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
5643ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
5653ae02089SMasatake YAMATO }
5663ae02089SMasatake YAMATO else
5673ae02089SMasatake YAMATO {
5683ae02089SMasatake YAMATO if (d == '*')
5693ae02089SMasatake YAMATO {
57064a05963SMasatake YAMATO skipToCharacterInInputFile2('*', '/');
5713ae02089SMasatake YAMATO goto getNextChar;
5723ae02089SMasatake YAMATO }
5733ae02089SMasatake YAMATO else if (d == '/') /* is this the start of a comment? */
5743ae02089SMasatake YAMATO {
5754fffc5afSMasatake YAMATO skipToCharacterInInputFile ('\n');
5768bbb9d0dSColomban Wendling /* if we care about newlines, put it back so it is seen */
5778bbb9d0dSColomban Wendling if (include_newlines)
5788bbb9d0dSColomban Wendling ungetcToInputFile ('\n');
5793ae02089SMasatake YAMATO goto getNextChar;
5803ae02089SMasatake YAMATO }
5813ae02089SMasatake YAMATO else if (d == '>') /* is this the start of a comment? */
5823ae02089SMasatake YAMATO {
5833ae02089SMasatake YAMATO token->type = TOKEN_CLOSE_SGML;
584a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
5853ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
5863ae02089SMasatake YAMATO }
5873ae02089SMasatake YAMATO }
5883ae02089SMasatake YAMATO break;
5893ae02089SMasatake YAMATO }
5903ae02089SMasatake YAMATO
5913ae02089SMasatake YAMATO case '<':
5923ae02089SMasatake YAMATO {
5933ae02089SMasatake YAMATO /*
5943ae02089SMasatake YAMATO * An XML comment looks like this
5953ae02089SMasatake YAMATO * <!-- anything over multiple lines -->
5963ae02089SMasatake YAMATO */
597018bce0bSMasatake YAMATO int d = getcFromInputFile ();
5983ae02089SMasatake YAMATO
5993ae02089SMasatake YAMATO if ( (d != '!' ) && /* is this the start of a comment? */
6003ae02089SMasatake YAMATO (d != '/' ) && /* is this the start of a closing mx tag */
6013ae02089SMasatake YAMATO (d != 'm' ) && /* is this the start of a mx tag */
6023ae02089SMasatake YAMATO (d != 'f' ) && /* is this the start of a fx tag */
6033ae02089SMasatake YAMATO (d != 's' ) ) /* is this the start of a spark tag */
6043ae02089SMasatake YAMATO {
60561f14fa5SMasatake YAMATO ungetcToInputFile (d);
6063ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
607a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
6083ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
6093ae02089SMasatake YAMATO break;
6103ae02089SMasatake YAMATO }
6113ae02089SMasatake YAMATO else
6123ae02089SMasatake YAMATO {
6133ae02089SMasatake YAMATO if (d == '!')
6143ae02089SMasatake YAMATO {
615018bce0bSMasatake YAMATO int e = getcFromInputFile ();
6163ae02089SMasatake YAMATO if ( e != '-' ) /* is this the start of a comment? */
6173ae02089SMasatake YAMATO {
61861f14fa5SMasatake YAMATO ungetcToInputFile (e);
61961f14fa5SMasatake YAMATO ungetcToInputFile (d);
6203ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
621a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
6223ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
6233ae02089SMasatake YAMATO }
6243ae02089SMasatake YAMATO else
6253ae02089SMasatake YAMATO {
6263ae02089SMasatake YAMATO if (e == '-')
6273ae02089SMasatake YAMATO {
628018bce0bSMasatake YAMATO int f = getcFromInputFile ();
6293ae02089SMasatake YAMATO if ( f != '-' ) /* is this the start of a comment? */
6303ae02089SMasatake YAMATO {
63161f14fa5SMasatake YAMATO ungetcToInputFile (f);
63261f14fa5SMasatake YAMATO ungetcToInputFile (e);
63361f14fa5SMasatake YAMATO ungetcToInputFile (d);
6343ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
635a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
6363ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
6373ae02089SMasatake YAMATO }
6383ae02089SMasatake YAMATO else
6393ae02089SMasatake YAMATO {
6403ae02089SMasatake YAMATO if (f == '-')
6413ae02089SMasatake YAMATO {
6423ae02089SMasatake YAMATO do
6433ae02089SMasatake YAMATO {
6444fffc5afSMasatake YAMATO skipToCharacterInInputFile ('-');
645018bce0bSMasatake YAMATO c = getcFromInputFile ();
6463ae02089SMasatake YAMATO if (c == '-')
6473ae02089SMasatake YAMATO {
648018bce0bSMasatake YAMATO d = getcFromInputFile ();
6493ae02089SMasatake YAMATO if (d == '>')
6503ae02089SMasatake YAMATO break;
6513ae02089SMasatake YAMATO else
6523ae02089SMasatake YAMATO {
65361f14fa5SMasatake YAMATO ungetcToInputFile (d);
65461f14fa5SMasatake YAMATO ungetcToInputFile (c);
6553ae02089SMasatake YAMATO }
6563ae02089SMasatake YAMATO break;
6573ae02089SMasatake YAMATO }
6583ae02089SMasatake YAMATO else
65961f14fa5SMasatake YAMATO ungetcToInputFile (c);
6603ae02089SMasatake YAMATO } while (c != EOF && c != '\0');
6613ae02089SMasatake YAMATO goto getNextChar;
6623ae02089SMasatake YAMATO }
6633ae02089SMasatake YAMATO }
6643ae02089SMasatake YAMATO }
6653ae02089SMasatake YAMATO }
6663ae02089SMasatake YAMATO }
6673ae02089SMasatake YAMATO else if (d == 'm' || d == 'f' || d == 's' )
6683ae02089SMasatake YAMATO {
669018bce0bSMasatake YAMATO int e = getcFromInputFile ();
6703ae02089SMasatake YAMATO if ( (d == 'm' || d == 'f') && e != 'x' ) /* continuing an mx or fx tag */
6713ae02089SMasatake YAMATO {
67261f14fa5SMasatake YAMATO ungetcToInputFile (e);
67361f14fa5SMasatake YAMATO ungetcToInputFile (d);
6743ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
675a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
6763ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
6773ae02089SMasatake YAMATO break;
6783ae02089SMasatake YAMATO }
6793ae02089SMasatake YAMATO else
6803ae02089SMasatake YAMATO {
6813ae02089SMasatake YAMATO if ( (d == 'm' || d == 'f') && e == 'x' )
6823ae02089SMasatake YAMATO {
683018bce0bSMasatake YAMATO int f = getcFromInputFile ();
6843ae02089SMasatake YAMATO if ( f != ':' ) /* start of the tag */
6853ae02089SMasatake YAMATO {
68661f14fa5SMasatake YAMATO ungetcToInputFile (f);
68761f14fa5SMasatake YAMATO ungetcToInputFile (e);
68861f14fa5SMasatake YAMATO ungetcToInputFile (d);
6893ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
690a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
6913ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
6923ae02089SMasatake YAMATO break;
6933ae02089SMasatake YAMATO }
6943ae02089SMasatake YAMATO else
6953ae02089SMasatake YAMATO {
6963ae02089SMasatake YAMATO token->type = TOKEN_OPEN_MXML;
697a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
6983ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
6993ae02089SMasatake YAMATO break;
7003ae02089SMasatake YAMATO }
7013ae02089SMasatake YAMATO }
7023ae02089SMasatake YAMATO if ( d == 's' && e == ':') /* continuing a spark tag */
7033ae02089SMasatake YAMATO {
7043ae02089SMasatake YAMATO token->type = TOKEN_OPEN_MXML;
705a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
7063ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
7073ae02089SMasatake YAMATO break;
7083ae02089SMasatake YAMATO }
7093ae02089SMasatake YAMATO else
7103ae02089SMasatake YAMATO {
71161f14fa5SMasatake YAMATO ungetcToInputFile (e);
71261f14fa5SMasatake YAMATO ungetcToInputFile (d);
7133ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
714a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
7153ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
7163ae02089SMasatake YAMATO break;
7173ae02089SMasatake YAMATO }
7183ae02089SMasatake YAMATO }
7193ae02089SMasatake YAMATO }
7203ae02089SMasatake YAMATO else if (d == '/')
7213ae02089SMasatake YAMATO {
722018bce0bSMasatake YAMATO int e = getcFromInputFile ();
7233ae02089SMasatake YAMATO if ( !(e == 'm' || e == 'f' || e == 's' ))
7243ae02089SMasatake YAMATO {
72561f14fa5SMasatake YAMATO ungetcToInputFile (e);
72661f14fa5SMasatake YAMATO ungetcToInputFile (d);
7273ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
728a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
7293ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
7303ae02089SMasatake YAMATO break;
7313ae02089SMasatake YAMATO }
7323ae02089SMasatake YAMATO else
7333ae02089SMasatake YAMATO {
734018bce0bSMasatake YAMATO int f = getcFromInputFile ();
7353ae02089SMasatake YAMATO if ( (e == 'm' || e == 'f') && f != 'x' ) /* continuing an mx or fx tag */
7363ae02089SMasatake YAMATO {
73761f14fa5SMasatake YAMATO ungetcToInputFile (f);
73861f14fa5SMasatake YAMATO ungetcToInputFile (e);
7393ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
740a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
7413ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
7423ae02089SMasatake YAMATO break;
7433ae02089SMasatake YAMATO }
7443ae02089SMasatake YAMATO else
7453ae02089SMasatake YAMATO {
7463ae02089SMasatake YAMATO if (f == 'x')
7473ae02089SMasatake YAMATO {
748018bce0bSMasatake YAMATO int g = getcFromInputFile ();
7493ae02089SMasatake YAMATO if ( g != ':' ) /* is this the start of a comment? */
7503ae02089SMasatake YAMATO {
75161f14fa5SMasatake YAMATO ungetcToInputFile (g);
75261f14fa5SMasatake YAMATO ungetcToInputFile (f);
75361f14fa5SMasatake YAMATO ungetcToInputFile (e);
7543ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
755a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
7563ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
7573ae02089SMasatake YAMATO break;
7583ae02089SMasatake YAMATO }
7593ae02089SMasatake YAMATO else
7603ae02089SMasatake YAMATO {
7613ae02089SMasatake YAMATO token->type = TOKEN_CLOSE_MXML;
762a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
7633ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
7643ae02089SMasatake YAMATO break;
7653ae02089SMasatake YAMATO }
7663ae02089SMasatake YAMATO }
7673ae02089SMasatake YAMATO if ( e == 's' && f == ':') /* continuing a spark tag */
7683ae02089SMasatake YAMATO {
7693ae02089SMasatake YAMATO token->type = TOKEN_CLOSE_MXML;
770a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
7713ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
7723ae02089SMasatake YAMATO break;
7733ae02089SMasatake YAMATO }
7743ae02089SMasatake YAMATO else
7753ae02089SMasatake YAMATO {
77661f14fa5SMasatake YAMATO ungetcToInputFile (f);
77761f14fa5SMasatake YAMATO ungetcToInputFile (e);
7783ae02089SMasatake YAMATO token->type = TOKEN_LESS_THAN;
779a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
7803ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
7813ae02089SMasatake YAMATO break;
7823ae02089SMasatake YAMATO }
7833ae02089SMasatake YAMATO }
7843ae02089SMasatake YAMATO }
7853ae02089SMasatake YAMATO }
7863ae02089SMasatake YAMATO }
7873ae02089SMasatake YAMATO break;
7883ae02089SMasatake YAMATO }
7893ae02089SMasatake YAMATO
7903ae02089SMasatake YAMATO case '>':
7913ae02089SMasatake YAMATO token->type = TOKEN_GREATER_THAN;
792a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
7933ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
7943ae02089SMasatake YAMATO break;
7953ae02089SMasatake YAMATO
7963ae02089SMasatake YAMATO case '!':
7973ae02089SMasatake YAMATO token->type = TOKEN_EXCLAMATION;
798a31b37dcSMasatake YAMATO /*token->lineNumber = getInputLineNumber ();
7993ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();*/
8003ae02089SMasatake YAMATO break;
8013ae02089SMasatake YAMATO
8023ae02089SMasatake YAMATO default:
8033ae02089SMasatake YAMATO if (! isIdentChar (c))
8043ae02089SMasatake YAMATO token->type = TOKEN_UNDEFINED;
8053ae02089SMasatake YAMATO else
8063ae02089SMasatake YAMATO {
8073ae02089SMasatake YAMATO parseIdentifier (token->string, c);
808a31b37dcSMasatake YAMATO token->lineNumber = getInputLineNumber ();
8093ae02089SMasatake YAMATO token->filePosition = getInputFilePosition ();
810970f6116SJiří Techet token->keyword = lookupCaseKeyword (vStringValue (token->string), Lang_flex);
8113ae02089SMasatake YAMATO if (isKeyword (token, KEYWORD_NONE))
8123ae02089SMasatake YAMATO token->type = TOKEN_IDENTIFIER;
8133ae02089SMasatake YAMATO else
8143ae02089SMasatake YAMATO token->type = TOKEN_KEYWORD;
8153ae02089SMasatake YAMATO }
8163ae02089SMasatake YAMATO break;
8173ae02089SMasatake YAMATO }
8188bbb9d0dSColomban Wendling
8198bbb9d0dSColomban Wendling if (include_newlines && newline_encountered)
8208bbb9d0dSColomban Wendling {
8218bbb9d0dSColomban Wendling /* This isn't strictly correct per the standard, but following the
8228bbb9d0dSColomban Wendling * real rules means understanding all statements, and that's not
8238bbb9d0dSColomban Wendling * what the parser currently does. What we do here is a guess, by
8248bbb9d0dSColomban Wendling * avoiding inserting semicolons that would make the statement on
8258bbb9d0dSColomban Wendling * the left or right obviously invalid. Hopefully this should not
8268bbb9d0dSColomban Wendling * have false negatives (e.g. should not miss insertion of a semicolon)
8278bbb9d0dSColomban Wendling * but might have false positives (e.g. it will wrongfully emit a
8288bbb9d0dSColomban Wendling * semicolon sometimes, i.e. for the newline in "foo\n(bar)").
8298bbb9d0dSColomban Wendling * This should however be mostly harmless as we only deal with
8308bbb9d0dSColomban Wendling * newlines in specific situations where we know a false positive
8318bbb9d0dSColomban Wendling * wouldn't hurt too bad. */
8328bbb9d0dSColomban Wendling
8338bbb9d0dSColomban Wendling /* these already end a statement, so no need to duplicate it */
8348bbb9d0dSColomban Wendling #define IS_STMT_SEPARATOR(t) ((t) == TOKEN_SEMICOLON || \
8358bbb9d0dSColomban Wendling (t) == TOKEN_EOF || \
8368bbb9d0dSColomban Wendling (t) == TOKEN_COMMA || \
8378bbb9d0dSColomban Wendling (t) == TOKEN_OPEN_CURLY)
8388bbb9d0dSColomban Wendling /* these cannot be the start or end of a statement */
8398bbb9d0dSColomban Wendling #define IS_BINARY_OPERATOR(t) ((t) == TOKEN_EQUAL_SIGN || \
8408bbb9d0dSColomban Wendling (t) == TOKEN_COLON || \
8418bbb9d0dSColomban Wendling (t) == TOKEN_PERIOD || \
84222848dcdSColomban Wendling (t) == TOKEN_STAR || \
8438bbb9d0dSColomban Wendling (t) == TOKEN_FORWARD_SLASH || \
8448bbb9d0dSColomban Wendling (t) == TOKEN_QUESTION_MARK || \
8458bbb9d0dSColomban Wendling (t) == TOKEN_LESS_THAN || \
8468bbb9d0dSColomban Wendling (t) == TOKEN_GREATER_THAN || \
8478bbb9d0dSColomban Wendling (t) == TOKEN_BINARY_OPERATOR)
8488bbb9d0dSColomban Wendling
8498bbb9d0dSColomban Wendling if (! IS_STMT_SEPARATOR(LastTokenType) &&
8508bbb9d0dSColomban Wendling ! IS_STMT_SEPARATOR(token->type) &&
8518bbb9d0dSColomban Wendling ! IS_BINARY_OPERATOR(LastTokenType) &&
8528bbb9d0dSColomban Wendling ! IS_BINARY_OPERATOR(token->type) &&
8538bbb9d0dSColomban Wendling /* these cannot be followed by a semicolon */
8548bbb9d0dSColomban Wendling ! (LastTokenType == TOKEN_OPEN_PAREN ||
8558bbb9d0dSColomban Wendling LastTokenType == TOKEN_OPEN_SQUARE))
8568bbb9d0dSColomban Wendling {
8578bbb9d0dSColomban Wendling /* hold the token... */
8588bbb9d0dSColomban Wendling Assert (NextToken == NULL);
8598bbb9d0dSColomban Wendling NextToken = newToken ();
8608bbb9d0dSColomban Wendling copyToken (NextToken, token, false);
8618bbb9d0dSColomban Wendling
8628bbb9d0dSColomban Wendling /* ...and emit a semicolon instead */
8638bbb9d0dSColomban Wendling token->type = TOKEN_SEMICOLON;
8648bbb9d0dSColomban Wendling token->keyword = KEYWORD_NONE;
8658bbb9d0dSColomban Wendling vStringClear (token->string);
8663ae02089SMasatake YAMATO }
8673ae02089SMasatake YAMATO
8688bbb9d0dSColomban Wendling #undef IS_STMT_SEPARATOR
8698bbb9d0dSColomban Wendling #undef IS_BINARY_OPERATOR
8708bbb9d0dSColomban Wendling }
8718bbb9d0dSColomban Wendling
8728bbb9d0dSColomban Wendling LastTokenType = token->type;
8738bbb9d0dSColomban Wendling }
8748bbb9d0dSColomban Wendling
readToken(tokenInfo * const token)8758bbb9d0dSColomban Wendling static void readToken (tokenInfo *const token)
8763ae02089SMasatake YAMATO {
8778bbb9d0dSColomban Wendling readTokenFull (token, false);
8783ae02089SMasatake YAMATO }
8793ae02089SMasatake YAMATO
8803ae02089SMasatake YAMATO /*
8813ae02089SMasatake YAMATO * Token parsing functions
8823ae02089SMasatake YAMATO */
8833ae02089SMasatake YAMATO
skipArgumentList(tokenInfo * const token,bool include_newlines)8848bbb9d0dSColomban Wendling static void skipArgumentList (tokenInfo *const token, bool include_newlines)
8853ae02089SMasatake YAMATO {
8863ae02089SMasatake YAMATO int nest_level = 0;
8873ae02089SMasatake YAMATO
8883ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_PAREN)) /* arguments? */
8893ae02089SMasatake YAMATO {
8903ae02089SMasatake YAMATO nest_level++;
8918bbb9d0dSColomban Wendling while (nest_level > 0 && ! isType (token, TOKEN_EOF))
8923ae02089SMasatake YAMATO {
8933ae02089SMasatake YAMATO readToken (token);
8943ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_PAREN))
8953ae02089SMasatake YAMATO nest_level++;
8968bbb9d0dSColomban Wendling else if (isType (token, TOKEN_CLOSE_PAREN))
8973ae02089SMasatake YAMATO nest_level--;
8983ae02089SMasatake YAMATO }
8998bbb9d0dSColomban Wendling readTokenFull (token, include_newlines);
9003ae02089SMasatake YAMATO }
9013ae02089SMasatake YAMATO }
9023ae02089SMasatake YAMATO
skipArrayList(tokenInfo * const token,bool include_newlines)9038bbb9d0dSColomban Wendling static void skipArrayList (tokenInfo *const token, bool include_newlines)
9043ae02089SMasatake YAMATO {
9053ae02089SMasatake YAMATO int nest_level = 0;
9063ae02089SMasatake YAMATO
9073ae02089SMasatake YAMATO /*
9083ae02089SMasatake YAMATO * Handle square brackets
9093ae02089SMasatake YAMATO * var name[1]
9103ae02089SMasatake YAMATO * So we must check for nested open and closing square brackets
9113ae02089SMasatake YAMATO */
9123ae02089SMasatake YAMATO
9133ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_SQUARE)) /* arguments? */
9143ae02089SMasatake YAMATO {
9153ae02089SMasatake YAMATO nest_level++;
9168bbb9d0dSColomban Wendling while (nest_level > 0 && ! isType (token, TOKEN_EOF))
9173ae02089SMasatake YAMATO {
9183ae02089SMasatake YAMATO readToken (token);
9193ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_SQUARE))
9203ae02089SMasatake YAMATO nest_level++;
9218bbb9d0dSColomban Wendling else if (isType (token, TOKEN_CLOSE_SQUARE))
9223ae02089SMasatake YAMATO nest_level--;
9233ae02089SMasatake YAMATO }
9248bbb9d0dSColomban Wendling readTokenFull (token, include_newlines);
9253ae02089SMasatake YAMATO }
9263ae02089SMasatake YAMATO }
9273ae02089SMasatake YAMATO
addContext(tokenInfo * const parent,const tokenInfo * const child)9283ae02089SMasatake YAMATO static void addContext (tokenInfo* const parent, const tokenInfo* const child)
9293ae02089SMasatake YAMATO {
9303ae02089SMasatake YAMATO if (vStringLength (parent->string) > 0)
9313ae02089SMasatake YAMATO {
9321da6e7e4SMasatake YAMATO vStringPut (parent->string, '.');
9333ae02089SMasatake YAMATO }
9344e6bcb7bSColomban Wendling vStringCat (parent->string, child->string);
9353ae02089SMasatake YAMATO }
9363ae02089SMasatake YAMATO
addToScope(tokenInfo * const token,const vString * const extra)9378bbb9d0dSColomban Wendling static void addToScope (tokenInfo* const token, const vString* const extra)
9383ae02089SMasatake YAMATO {
9393ae02089SMasatake YAMATO if (vStringLength (token->scope) > 0)
9403ae02089SMasatake YAMATO {
9411da6e7e4SMasatake YAMATO vStringPut (token->scope, '.');
9423ae02089SMasatake YAMATO }
9434e6bcb7bSColomban Wendling vStringCat (token->scope, extra);
9443ae02089SMasatake YAMATO }
9453ae02089SMasatake YAMATO
9463ae02089SMasatake YAMATO /*
9473ae02089SMasatake YAMATO * Scanning functions
9483ae02089SMasatake YAMATO */
9493ae02089SMasatake YAMATO
findCmdTerm(tokenInfo * const token,bool include_newlines,bool include_commas)9508bbb9d0dSColomban Wendling static bool findCmdTerm (tokenInfo *const token, bool include_newlines,
9518bbb9d0dSColomban Wendling bool include_commas)
9523ae02089SMasatake YAMATO {
9533ae02089SMasatake YAMATO /*
9543ae02089SMasatake YAMATO * Read until we find either a semicolon or closing brace.
9553ae02089SMasatake YAMATO * Any nested braces will be handled within.
9563ae02089SMasatake YAMATO */
9578bbb9d0dSColomban Wendling while (! isType (token, TOKEN_SEMICOLON) &&
9588bbb9d0dSColomban Wendling ! isType (token, TOKEN_CLOSE_CURLY) &&
9598bbb9d0dSColomban Wendling ! (include_commas && isType (token, TOKEN_COMMA)) &&
9608bbb9d0dSColomban Wendling ! isType (token, TOKEN_EOF))
9613ae02089SMasatake YAMATO {
9623ae02089SMasatake YAMATO /* Handle nested blocks */
9633ae02089SMasatake YAMATO if ( isType (token, TOKEN_OPEN_CURLY))
9643ae02089SMasatake YAMATO {
9658bbb9d0dSColomban Wendling parseBlock (token, NULL);
9668bbb9d0dSColomban Wendling readTokenFull (token, include_newlines);
9673ae02089SMasatake YAMATO }
9683ae02089SMasatake YAMATO else if ( isType (token, TOKEN_OPEN_PAREN) )
9693ae02089SMasatake YAMATO {
9708bbb9d0dSColomban Wendling skipArgumentList(token, include_newlines);
9718bbb9d0dSColomban Wendling }
9728bbb9d0dSColomban Wendling else if ( isType (token, TOKEN_OPEN_SQUARE) )
9738bbb9d0dSColomban Wendling {
9748bbb9d0dSColomban Wendling skipArrayList(token, include_newlines);
9753ae02089SMasatake YAMATO }
9763ae02089SMasatake YAMATO else
9773ae02089SMasatake YAMATO {
9788bbb9d0dSColomban Wendling readTokenFull (token, include_newlines);
9793ae02089SMasatake YAMATO }
9803ae02089SMasatake YAMATO }
9818bbb9d0dSColomban Wendling
9828bbb9d0dSColomban Wendling return isType (token, TOKEN_SEMICOLON);
9833ae02089SMasatake YAMATO }
9843ae02089SMasatake YAMATO
parseSwitch(tokenInfo * const token)9853ae02089SMasatake YAMATO static void parseSwitch (tokenInfo *const token)
9863ae02089SMasatake YAMATO {
9873ae02089SMasatake YAMATO /*
9883ae02089SMasatake YAMATO * switch (expression) {
9893ae02089SMasatake YAMATO * case value1:
9903ae02089SMasatake YAMATO * statement;
9913ae02089SMasatake YAMATO * break;
9923ae02089SMasatake YAMATO * case value2:
9933ae02089SMasatake YAMATO * statement;
9943ae02089SMasatake YAMATO * break;
9953ae02089SMasatake YAMATO * default : statement;
9963ae02089SMasatake YAMATO * }
9973ae02089SMasatake YAMATO */
9983ae02089SMasatake YAMATO
9993ae02089SMasatake YAMATO readToken (token);
10003ae02089SMasatake YAMATO
10013ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_PAREN))
10023ae02089SMasatake YAMATO {
10038bbb9d0dSColomban Wendling skipArgumentList(token, false);
10043ae02089SMasatake YAMATO }
10053ae02089SMasatake YAMATO
10063ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_CURLY))
10073ae02089SMasatake YAMATO {
10088bbb9d0dSColomban Wendling parseBlock (token, NULL);
10098bbb9d0dSColomban Wendling }
10103ae02089SMasatake YAMATO }
10113ae02089SMasatake YAMATO
parseLoop(tokenInfo * const token)10128bbb9d0dSColomban Wendling static bool parseLoop (tokenInfo *const token)
10133ae02089SMasatake YAMATO {
10143ae02089SMasatake YAMATO /*
10153ae02089SMasatake YAMATO * Handles these statements
10163ae02089SMasatake YAMATO * for (x=0; x<3; x++)
10173ae02089SMasatake YAMATO * document.write("This text is repeated three times<br>");
10183ae02089SMasatake YAMATO *
10193ae02089SMasatake YAMATO * for (x=0; x<3; x++)
10203ae02089SMasatake YAMATO * {
10213ae02089SMasatake YAMATO * document.write("This text is repeated three times<br>");
10223ae02089SMasatake YAMATO * }
10233ae02089SMasatake YAMATO *
10243ae02089SMasatake YAMATO * while (number<5){
10253ae02089SMasatake YAMATO * document.write(number+"<br>");
10263ae02089SMasatake YAMATO * number++;
10273ae02089SMasatake YAMATO * }
10283ae02089SMasatake YAMATO *
10293ae02089SMasatake YAMATO * do{
10303ae02089SMasatake YAMATO * document.write(number+"<br>");
10313ae02089SMasatake YAMATO * number++;
10323ae02089SMasatake YAMATO * }
10333ae02089SMasatake YAMATO * while (number<5);
10343ae02089SMasatake YAMATO */
10358bbb9d0dSColomban Wendling bool is_terminated = true;
10363ae02089SMasatake YAMATO
10373ae02089SMasatake YAMATO if (isKeyword (token, KEYWORD_for) || isKeyword (token, KEYWORD_while))
10383ae02089SMasatake YAMATO {
10393ae02089SMasatake YAMATO readToken(token);
10403ae02089SMasatake YAMATO
10413ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_PAREN))
10423ae02089SMasatake YAMATO {
10438bbb9d0dSColomban Wendling skipArgumentList(token, false);
10443ae02089SMasatake YAMATO }
10453ae02089SMasatake YAMATO
10463ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_CURLY))
10473ae02089SMasatake YAMATO {
10488bbb9d0dSColomban Wendling parseBlock (token, NULL);
10493ae02089SMasatake YAMATO }
10503ae02089SMasatake YAMATO else
10513ae02089SMasatake YAMATO {
10528bbb9d0dSColomban Wendling is_terminated = parseLine(token);
10533ae02089SMasatake YAMATO }
10543ae02089SMasatake YAMATO }
10553ae02089SMasatake YAMATO else if (isKeyword (token, KEYWORD_do))
10563ae02089SMasatake YAMATO {
10573ae02089SMasatake YAMATO readToken(token);
10583ae02089SMasatake YAMATO
10593ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_CURLY))
10603ae02089SMasatake YAMATO {
10618bbb9d0dSColomban Wendling parseBlock (token, NULL);
10623ae02089SMasatake YAMATO }
10633ae02089SMasatake YAMATO else
10643ae02089SMasatake YAMATO {
10658bbb9d0dSColomban Wendling is_terminated = parseLine(token);
10663ae02089SMasatake YAMATO }
10673ae02089SMasatake YAMATO
10688bbb9d0dSColomban Wendling if (is_terminated)
10693ae02089SMasatake YAMATO readToken(token);
10703ae02089SMasatake YAMATO
10713ae02089SMasatake YAMATO if (isKeyword (token, KEYWORD_while))
10723ae02089SMasatake YAMATO {
10733ae02089SMasatake YAMATO readToken(token);
10743ae02089SMasatake YAMATO
10753ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_PAREN))
10763ae02089SMasatake YAMATO {
10778bbb9d0dSColomban Wendling skipArgumentList(token, true);
10788bbb9d0dSColomban Wendling }
10798bbb9d0dSColomban Wendling if (! isType (token, TOKEN_SEMICOLON))
10808bbb9d0dSColomban Wendling {
10818bbb9d0dSColomban Wendling /* oddly enough, `do {} while (0) var foo = 42` is perfectly
10828bbb9d0dSColomban Wendling * valid AS, so explicitly handle the remaining of the line
10838bbb9d0dSColomban Wendling * for the sake of the root scope handling (as parseActionScript()
10848bbb9d0dSColomban Wendling * always advances a token not to ever get stuck) */
10858bbb9d0dSColomban Wendling is_terminated = parseLine(token);
10863ae02089SMasatake YAMATO }
10873ae02089SMasatake YAMATO }
10883ae02089SMasatake YAMATO }
10898bbb9d0dSColomban Wendling
10908bbb9d0dSColomban Wendling return is_terminated;
10913ae02089SMasatake YAMATO }
10923ae02089SMasatake YAMATO
parseIf(tokenInfo * const token)1093ce990805SThomas Braun static bool parseIf (tokenInfo *const token)
10943ae02089SMasatake YAMATO {
1095ce990805SThomas Braun bool read_next_token = true;
10963ae02089SMasatake YAMATO /*
10973ae02089SMasatake YAMATO * If statements have two forms
10983ae02089SMasatake YAMATO * if ( ... )
10993ae02089SMasatake YAMATO * one line;
11003ae02089SMasatake YAMATO *
11013ae02089SMasatake YAMATO * if ( ... )
11023ae02089SMasatake YAMATO * statement;
11033ae02089SMasatake YAMATO * else
11043ae02089SMasatake YAMATO * statement
11053ae02089SMasatake YAMATO *
11063ae02089SMasatake YAMATO * if ( ... ) {
11073ae02089SMasatake YAMATO * multiple;
11083ae02089SMasatake YAMATO * statements;
11093ae02089SMasatake YAMATO * }
11103ae02089SMasatake YAMATO *
11113ae02089SMasatake YAMATO *
11123ae02089SMasatake YAMATO * if ( ... ) {
11133ae02089SMasatake YAMATO * return elem
11143ae02089SMasatake YAMATO * }
11153ae02089SMasatake YAMATO *
11163ae02089SMasatake YAMATO * This example if correctly written, but the
11173ae02089SMasatake YAMATO * else contains only 1 statement without a terminator
11183ae02089SMasatake YAMATO * since the function finishes with the closing brace.
11193ae02089SMasatake YAMATO *
11203ae02089SMasatake YAMATO * function a(flag){
11213ae02089SMasatake YAMATO * if(flag)
11223ae02089SMasatake YAMATO * test(1);
11233ae02089SMasatake YAMATO * else
11243ae02089SMasatake YAMATO * test(2)
11253ae02089SMasatake YAMATO * }
11263ae02089SMasatake YAMATO *
11273ae02089SMasatake YAMATO * TODO: Deal with statements that can optional end
11283ae02089SMasatake YAMATO * without a semi-colon. Currently this messes up
11293ae02089SMasatake YAMATO * the parsing of blocks.
11303ae02089SMasatake YAMATO * Need to somehow detect this has happened, and either
11313ae02089SMasatake YAMATO * backup a token, or skip reading the next token if
11323ae02089SMasatake YAMATO * that is possible from all code locations.
11333ae02089SMasatake YAMATO *
11343ae02089SMasatake YAMATO */
11353ae02089SMasatake YAMATO
11363ae02089SMasatake YAMATO readToken (token);
11373ae02089SMasatake YAMATO
11383ae02089SMasatake YAMATO if (isKeyword (token, KEYWORD_if))
11393ae02089SMasatake YAMATO {
11403ae02089SMasatake YAMATO /*
11413ae02089SMasatake YAMATO * Check for an "else if" and consume the "if"
11423ae02089SMasatake YAMATO */
11433ae02089SMasatake YAMATO readToken (token);
11443ae02089SMasatake YAMATO }
11453ae02089SMasatake YAMATO
11463ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_PAREN))
11473ae02089SMasatake YAMATO {
11488bbb9d0dSColomban Wendling skipArgumentList(token, false);
11493ae02089SMasatake YAMATO }
11503ae02089SMasatake YAMATO
11513ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_CURLY))
11523ae02089SMasatake YAMATO {
11538bbb9d0dSColomban Wendling parseBlock (token, NULL);
11543ae02089SMasatake YAMATO }
11553ae02089SMasatake YAMATO else
11563ae02089SMasatake YAMATO {
11578bbb9d0dSColomban Wendling /* The next token should only be read if this statement had its own
11588bbb9d0dSColomban Wendling * terminator */
11598bbb9d0dSColomban Wendling read_next_token = findCmdTerm (token, true, false);
11603ae02089SMasatake YAMATO }
11613ae02089SMasatake YAMATO return read_next_token;
11623ae02089SMasatake YAMATO }
11633ae02089SMasatake YAMATO
parseImport(tokenInfo * const token)116422848dcdSColomban Wendling static bool parseImport (tokenInfo *const token)
116522848dcdSColomban Wendling {
116622848dcdSColomban Wendling if (! isKeyword (token, KEYWORD_import))
116722848dcdSColomban Wendling return false;
116822848dcdSColomban Wendling
116922848dcdSColomban Wendling readToken (token);
117022848dcdSColomban Wendling
117122848dcdSColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
117222848dcdSColomban Wendling {
117322848dcdSColomban Wendling tokenInfo *const name = newToken ();
117422848dcdSColomban Wendling
117522848dcdSColomban Wendling copyToken (name, token, true);
117622848dcdSColomban Wendling readToken (token);
117722848dcdSColomban Wendling while (isType (token, TOKEN_PERIOD))
117822848dcdSColomban Wendling {
117922848dcdSColomban Wendling vStringPut (name->string, '.');
118022848dcdSColomban Wendling readToken (token);
118122848dcdSColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
118222848dcdSColomban Wendling vStringCat (name->string, token->string);
118322848dcdSColomban Wendling else if (isType (token, TOKEN_STAR))
118422848dcdSColomban Wendling vStringPut (name->string, '*');
118522848dcdSColomban Wendling if (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_STAR))
118622848dcdSColomban Wendling readToken (token);
118722848dcdSColomban Wendling }
118822848dcdSColomban Wendling
118922848dcdSColomban Wendling makeFlexTag (name, FLEXTAG_IMPORT);
119022848dcdSColomban Wendling deleteToken (name);
119122848dcdSColomban Wendling }
119222848dcdSColomban Wendling
119322848dcdSColomban Wendling return isType (token, TOKEN_SEMICOLON);
119422848dcdSColomban Wendling }
119522848dcdSColomban Wendling
parseFunction(tokenInfo * const token)11963ae02089SMasatake YAMATO static void parseFunction (tokenInfo *const token)
11973ae02089SMasatake YAMATO {
11983ae02089SMasatake YAMATO tokenInfo *const name = newToken ();
119941d17124SColomban Wendling flexKind kind = FLEXTAG_FUNCTION;
12003ae02089SMasatake YAMATO
12013ae02089SMasatake YAMATO /*
12023ae02089SMasatake YAMATO * This deals with these formats
12033ae02089SMasatake YAMATO * private static function ioErrorHandler( event:IOErrorEvent ):void {
1204644209f6SColomban Wendling * public function get prop():String {}
1205644209f6SColomban Wendling * public function set prop(param:String):void {}
12063ae02089SMasatake YAMATO */
12073ae02089SMasatake YAMATO
12083ae02089SMasatake YAMATO if ( isKeyword(token, KEYWORD_function) )
12093ae02089SMasatake YAMATO {
12103ae02089SMasatake YAMATO readToken (token);
12113ae02089SMasatake YAMATO }
12123ae02089SMasatake YAMATO
1213644209f6SColomban Wendling /* getter and setter */
1214644209f6SColomban Wendling if (isKeyword (token, KEYWORD_get) ||
1215644209f6SColomban Wendling isKeyword (token, KEYWORD_set))
1216644209f6SColomban Wendling {
121741d17124SColomban Wendling kind = FLEXTAG_PROPERTY;
1218644209f6SColomban Wendling readToken (token);
1219644209f6SColomban Wendling }
1220644209f6SColomban Wendling
12218bbb9d0dSColomban Wendling copyToken (name, token, true);
12223ae02089SMasatake YAMATO /* Add scope in case this is an INNER function
12233ae02089SMasatake YAMATO addToScope(name, token->scope);
12243ae02089SMasatake YAMATO */
12253ae02089SMasatake YAMATO
12263ae02089SMasatake YAMATO DebugStatement (
12273ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
12283ae02089SMasatake YAMATO , "\n parseFunction: token isClass:%d scope:%s name:%s\n"
12293ae02089SMasatake YAMATO , token->isClass
12303ae02089SMasatake YAMATO , vStringValue(token->scope)
12313ae02089SMasatake YAMATO , vStringValue(token->string)
12323ae02089SMasatake YAMATO );
12333ae02089SMasatake YAMATO );
12343ae02089SMasatake YAMATO DebugStatement (
12353ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
12363ae02089SMasatake YAMATO , "\n parseFunction: name isClass:%d scope:%s name:%s\n"
12373ae02089SMasatake YAMATO , name->isClass
12383ae02089SMasatake YAMATO , vStringValue(name->scope)
12393ae02089SMasatake YAMATO , vStringValue(name->string)
12403ae02089SMasatake YAMATO );
12413ae02089SMasatake YAMATO );
12423ae02089SMasatake YAMATO
12433ae02089SMasatake YAMATO readToken (token);
12443ae02089SMasatake YAMATO
12453ae02089SMasatake YAMATO if ( isType (token, TOKEN_OPEN_PAREN) )
12468bbb9d0dSColomban Wendling skipArgumentList(token, false);
12473ae02089SMasatake YAMATO
12483ae02089SMasatake YAMATO if ( isType (token, TOKEN_COLON) )
12493ae02089SMasatake YAMATO {
12503ae02089SMasatake YAMATO /*
12513ae02089SMasatake YAMATO * function fname ():ReturnType
12523ae02089SMasatake YAMATO */
12533ae02089SMasatake YAMATO readToken (token);
12541fd37dabSColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
12553ae02089SMasatake YAMATO readToken (token);
12563ae02089SMasatake YAMATO }
12573ae02089SMasatake YAMATO
12583ae02089SMasatake YAMATO if ( isType (token, TOKEN_OPEN_CURLY) )
12593ae02089SMasatake YAMATO {
12603ae02089SMasatake YAMATO DebugStatement (
12613ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
12623ae02089SMasatake YAMATO , "\n parseFunction end: name isClass:%d scope:%s name:%s\n"
12633ae02089SMasatake YAMATO , name->isClass
12643ae02089SMasatake YAMATO , vStringValue(name->scope)
12653ae02089SMasatake YAMATO , vStringValue(name->string)
12663ae02089SMasatake YAMATO );
12673ae02089SMasatake YAMATO );
12688bbb9d0dSColomban Wendling parseBlock (token, name->string);
12693ae02089SMasatake YAMATO DebugStatement (
12703ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
12713ae02089SMasatake YAMATO , "\n parseFunction end2: token isClass:%d scope:%s name:%s\n"
12723ae02089SMasatake YAMATO , token->isClass
12733ae02089SMasatake YAMATO , vStringValue(token->scope)
12743ae02089SMasatake YAMATO , vStringValue(token->string)
12753ae02089SMasatake YAMATO );
12763ae02089SMasatake YAMATO );
12773ae02089SMasatake YAMATO DebugStatement (
12783ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
12793ae02089SMasatake YAMATO , "\n parseFunction end2: token isClass:%d scope:%s name:%s\n"
12803ae02089SMasatake YAMATO , token->isClass
12813ae02089SMasatake YAMATO , vStringValue(token->scope)
12823ae02089SMasatake YAMATO , vStringValue(token->string)
12833ae02089SMasatake YAMATO );
12843ae02089SMasatake YAMATO );
12853ae02089SMasatake YAMATO DebugStatement (
12863ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
12873ae02089SMasatake YAMATO , "\n parseFunction end3: name isClass:%d scope:%s name:%s\n"
12883ae02089SMasatake YAMATO , name->isClass
12893ae02089SMasatake YAMATO , vStringValue(name->scope)
12903ae02089SMasatake YAMATO , vStringValue(name->string)
12913ae02089SMasatake YAMATO );
12923ae02089SMasatake YAMATO );
129341d17124SColomban Wendling if (kind == FLEXTAG_FUNCTION)
12943ae02089SMasatake YAMATO makeFunctionTag (name);
129541d17124SColomban Wendling else
129641d17124SColomban Wendling makeFlexTag (name, kind);
12973ae02089SMasatake YAMATO }
12983ae02089SMasatake YAMATO
12998bbb9d0dSColomban Wendling findCmdTerm (token, false, false);
13003ae02089SMasatake YAMATO
13013ae02089SMasatake YAMATO deleteToken (name);
13023ae02089SMasatake YAMATO }
13033ae02089SMasatake YAMATO
13048bbb9d0dSColomban Wendling /* Parses a block surrounded by curly braces.
13058bbb9d0dSColomban Wendling * @p parentScope is the scope name for this block, or NULL for unnamed scopes */
parseBlock(tokenInfo * const token,const vString * const parentScope)13068bbb9d0dSColomban Wendling static bool parseBlock (tokenInfo *const token, const vString *const parentScope)
13073ae02089SMasatake YAMATO {
1308ce990805SThomas Braun bool read_next_token = true;
13093ae02089SMasatake YAMATO vString * saveScope = vStringNew ();
13103ae02089SMasatake YAMATO
13113ae02089SMasatake YAMATO vStringCopy (saveScope, token->scope);
13128bbb9d0dSColomban Wendling if (parentScope)
13138bbb9d0dSColomban Wendling {
13148bbb9d0dSColomban Wendling addToScope (token, parentScope);
13153ae02089SMasatake YAMATO token->nestLevel++;
13168bbb9d0dSColomban Wendling }
13178bbb9d0dSColomban Wendling
13183ae02089SMasatake YAMATO DebugStatement (
13193ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
13203ae02089SMasatake YAMATO , "\n parseBlock start: token isClass:%d scope:%s name:%s\n"
13213ae02089SMasatake YAMATO , token->isClass
13223ae02089SMasatake YAMATO , vStringValue(token->scope)
13233ae02089SMasatake YAMATO , vStringValue(token->string)
13243ae02089SMasatake YAMATO );
13253ae02089SMasatake YAMATO );
13263ae02089SMasatake YAMATO /*
13273ae02089SMasatake YAMATO * Make this routine a bit more forgiving.
13283ae02089SMasatake YAMATO * If called on an open_curly advance it
13293ae02089SMasatake YAMATO */
13308bbb9d0dSColomban Wendling if (isType (token, TOKEN_OPEN_CURLY))
13313ae02089SMasatake YAMATO readToken(token);
13323ae02089SMasatake YAMATO
13333ae02089SMasatake YAMATO if (! isType (token, TOKEN_CLOSE_CURLY))
13343ae02089SMasatake YAMATO {
13353ae02089SMasatake YAMATO /*
13363ae02089SMasatake YAMATO * Read until we find the closing brace,
13373ae02089SMasatake YAMATO * any nested braces will be handled within
13383ae02089SMasatake YAMATO */
13393ae02089SMasatake YAMATO do
13403ae02089SMasatake YAMATO {
13413ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_CURLY))
13423ae02089SMasatake YAMATO {
13433ae02089SMasatake YAMATO /* Handle nested blocks */
13448bbb9d0dSColomban Wendling parseBlock (token, NULL);
13453ae02089SMasatake YAMATO }
13463ae02089SMasatake YAMATO else
13473ae02089SMasatake YAMATO {
13483ae02089SMasatake YAMATO /*
13493ae02089SMasatake YAMATO * It is possible for a line to have no terminator
13503ae02089SMasatake YAMATO * if the following line is a closing brace.
13513ae02089SMasatake YAMATO * parseLine will detect this case and indicate
13523ae02089SMasatake YAMATO * whether we should read an additional token.
13533ae02089SMasatake YAMATO */
13543ae02089SMasatake YAMATO read_next_token = parseLine (token);
13553ae02089SMasatake YAMATO }
13563ae02089SMasatake YAMATO
13573ae02089SMasatake YAMATO /*
13583ae02089SMasatake YAMATO * Always read a new token unless we find a statement without
13593ae02089SMasatake YAMATO * a ending terminator
13603ae02089SMasatake YAMATO */
13613ae02089SMasatake YAMATO if( read_next_token )
13623ae02089SMasatake YAMATO readToken(token);
13633ae02089SMasatake YAMATO
13643ae02089SMasatake YAMATO /*
13653ae02089SMasatake YAMATO * If we find a statement without a terminator consider the
13663ae02089SMasatake YAMATO * block finished, otherwise the stack will be off by one.
13673ae02089SMasatake YAMATO */
13688bbb9d0dSColomban Wendling } while (! isType (token, TOKEN_EOF) &&
13698bbb9d0dSColomban Wendling ! isType (token, TOKEN_CLOSE_CURLY) && read_next_token);
13703ae02089SMasatake YAMATO }
13713ae02089SMasatake YAMATO
1372fb6e88e2SMasatake YAMATO vStringCopy(token->scope, saveScope);
13733ae02089SMasatake YAMATO vStringDelete(saveScope);
13748bbb9d0dSColomban Wendling if (parentScope)
13753ae02089SMasatake YAMATO token->nestLevel--;
13763ae02089SMasatake YAMATO
13773ae02089SMasatake YAMATO DebugStatement (
13783ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
13793ae02089SMasatake YAMATO , "\n parseBlock end: token isClass:%d scope:%s name:%s\n"
13803ae02089SMasatake YAMATO , token->isClass
13813ae02089SMasatake YAMATO , vStringValue(token->scope)
13823ae02089SMasatake YAMATO , vStringValue(token->string)
13833ae02089SMasatake YAMATO );
13843ae02089SMasatake YAMATO );
1385ce990805SThomas Braun return false;
13863ae02089SMasatake YAMATO }
13873ae02089SMasatake YAMATO
parseMethods(tokenInfo * const token,const tokenInfo * const class)13888bbb9d0dSColomban Wendling static void parseMethods (tokenInfo *const token, const tokenInfo *const class)
13893ae02089SMasatake YAMATO {
13903ae02089SMasatake YAMATO tokenInfo *const name = newToken ();
13918bbb9d0dSColomban Wendling vString *saveScope = vStringNew ();
13928bbb9d0dSColomban Wendling
13938bbb9d0dSColomban Wendling vStringCopy (saveScope, token->scope);
13948bbb9d0dSColomban Wendling addToScope (token, class->string);
13953ae02089SMasatake YAMATO
13963ae02089SMasatake YAMATO /*
13973ae02089SMasatake YAMATO * This deals with these formats
13983ae02089SMasatake YAMATO * validProperty : 2,
13993ae02089SMasatake YAMATO * validMethod : function(a,b) {}
14003ae02089SMasatake YAMATO * 'validMethod2' : function(a,b) {}
14013ae02089SMasatake YAMATO * container.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}
14023ae02089SMasatake YAMATO */
14033ae02089SMasatake YAMATO
14043ae02089SMasatake YAMATO do
14053ae02089SMasatake YAMATO {
14063ae02089SMasatake YAMATO readToken (token);
14078bbb9d0dSColomban Wendling if (isType (token, TOKEN_CLOSE_CURLY))
14088bbb9d0dSColomban Wendling {
14098bbb9d0dSColomban Wendling goto cleanUp;
14108bbb9d0dSColomban Wendling }
14118bbb9d0dSColomban Wendling
14123ae02089SMasatake YAMATO if (isType (token, TOKEN_STRING) || isKeyword(token, KEYWORD_NONE))
14133ae02089SMasatake YAMATO {
14148bbb9d0dSColomban Wendling copyToken (name, token, true);
14153ae02089SMasatake YAMATO
14163ae02089SMasatake YAMATO readToken (token);
14173ae02089SMasatake YAMATO if ( isType (token, TOKEN_COLON) )
14183ae02089SMasatake YAMATO {
14193ae02089SMasatake YAMATO readToken (token);
14203ae02089SMasatake YAMATO if ( isKeyword (token, KEYWORD_function) )
14213ae02089SMasatake YAMATO {
14223ae02089SMasatake YAMATO readToken (token);
14233ae02089SMasatake YAMATO if ( isType (token, TOKEN_OPEN_PAREN) )
14243ae02089SMasatake YAMATO {
14258bbb9d0dSColomban Wendling skipArgumentList(token, false);
14263ae02089SMasatake YAMATO }
14273ae02089SMasatake YAMATO
14283ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_CURLY))
14293ae02089SMasatake YAMATO {
14303ae02089SMasatake YAMATO makeFlexTag (name, FLEXTAG_METHOD);
14318bbb9d0dSColomban Wendling parseBlock (token, name->string);
14323ae02089SMasatake YAMATO
14333ae02089SMasatake YAMATO /*
14343ae02089SMasatake YAMATO * Read to the closing curly, check next
14353ae02089SMasatake YAMATO * token, if a comma, we must loop again
14363ae02089SMasatake YAMATO */
14373ae02089SMasatake YAMATO readToken (token);
14383ae02089SMasatake YAMATO }
14393ae02089SMasatake YAMATO }
14403ae02089SMasatake YAMATO else
14413ae02089SMasatake YAMATO {
14423ae02089SMasatake YAMATO makeFlexTag (name, FLEXTAG_PROPERTY);
14433ae02089SMasatake YAMATO
14443ae02089SMasatake YAMATO /*
14453ae02089SMasatake YAMATO * Read the next token, if a comma
14463ae02089SMasatake YAMATO * we must loop again
14473ae02089SMasatake YAMATO */
14483ae02089SMasatake YAMATO readToken (token);
14493ae02089SMasatake YAMATO }
14503ae02089SMasatake YAMATO }
14513ae02089SMasatake YAMATO }
14523ae02089SMasatake YAMATO } while ( isType(token, TOKEN_COMMA));
14533ae02089SMasatake YAMATO
14548bbb9d0dSColomban Wendling findCmdTerm (token, false, false);
14553ae02089SMasatake YAMATO
145617d3d2f0SMasatake YAMATO cleanUp:
14578bbb9d0dSColomban Wendling vStringCopy (token->scope, saveScope);
14588bbb9d0dSColomban Wendling vStringDelete (saveScope);
14593ae02089SMasatake YAMATO deleteToken (name);
14603ae02089SMasatake YAMATO }
14613ae02089SMasatake YAMATO
parseVar(tokenInfo * const token,bool is_public)1462ce990805SThomas Braun static bool parseVar (tokenInfo *const token, bool is_public)
14633ae02089SMasatake YAMATO {
14643ae02089SMasatake YAMATO tokenInfo *const name = newToken ();
1465ce990805SThomas Braun bool is_terminated = true;
146624528e6eSColomban Wendling flexKind kind = is_public ? FLEXTAG_VARIABLE : FLEXTAG_LOCALVAR;
14673ae02089SMasatake YAMATO
14683ae02089SMasatake YAMATO /*
14693ae02089SMasatake YAMATO * Variables are defined as:
14703ae02089SMasatake YAMATO * private static var lastFaultMessage:Date = new Date( 0 );
14713ae02089SMasatake YAMATO * private static var webRequests:ArrayCollection = new ArrayCollection();
14723ae02089SMasatake YAMATO */
14733ae02089SMasatake YAMATO
14743ae02089SMasatake YAMATO if ( isKeyword(token, KEYWORD_var) )
14753ae02089SMasatake YAMATO {
14763ae02089SMasatake YAMATO readToken(token);
14773ae02089SMasatake YAMATO }
147824528e6eSColomban Wendling else if (isKeyword(token, KEYWORD_const))
147924528e6eSColomban Wendling {
148024528e6eSColomban Wendling kind = FLEXTAG_CONST;
148124528e6eSColomban Wendling readToken(token);
148224528e6eSColomban Wendling }
14833ae02089SMasatake YAMATO
14843ae02089SMasatake YAMATO /* Variable name */
14858bbb9d0dSColomban Wendling copyToken (name, token, true);
14863ae02089SMasatake YAMATO readToken(token);
14873ae02089SMasatake YAMATO
14883ae02089SMasatake YAMATO if ( isType (token, TOKEN_COLON) )
14893ae02089SMasatake YAMATO {
14903ae02089SMasatake YAMATO /*
14913ae02089SMasatake YAMATO * var vname ():DataType = new Date();
14923ae02089SMasatake YAMATO * var vname ():DataType;
14933ae02089SMasatake YAMATO */
14943ae02089SMasatake YAMATO readToken (token);
14951fd37dabSColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
14963ae02089SMasatake YAMATO readToken (token);
14973ae02089SMasatake YAMATO }
14983ae02089SMasatake YAMATO
1499a14b72e8SColomban Wendling is_terminated = findCmdTerm (token, true, false);
15003ae02089SMasatake YAMATO
15013ae02089SMasatake YAMATO if ( isType (token, TOKEN_SEMICOLON) )
15023ae02089SMasatake YAMATO {
150324528e6eSColomban Wendling makeFlexTag (name, kind);
15043ae02089SMasatake YAMATO }
15053ae02089SMasatake YAMATO
15063ae02089SMasatake YAMATO deleteToken (name);
15073ae02089SMasatake YAMATO
15083ae02089SMasatake YAMATO return is_terminated;
15093ae02089SMasatake YAMATO }
15103ae02089SMasatake YAMATO
parsePackage(tokenInfo * const token)15113a43a456SColomban Wendling static void parsePackage (tokenInfo *const token)
15123a43a456SColomban Wendling {
15133a43a456SColomban Wendling tokenInfo *name = NULL;
15143a43a456SColomban Wendling
15153a43a456SColomban Wendling if (isKeyword (token, KEYWORD_package))
15163a43a456SColomban Wendling readToken(token);
15173a43a456SColomban Wendling
15187495a06bSColomban Wendling /* name is optional and can be qualified */
15193a43a456SColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
15203a43a456SColomban Wendling {
15213a43a456SColomban Wendling name = newToken ();
15223a43a456SColomban Wendling copyToken (name, token, true);
15233a43a456SColomban Wendling readToken (token);
15247495a06bSColomban Wendling
15257495a06bSColomban Wendling while (isType (token, TOKEN_PERIOD))
15267495a06bSColomban Wendling {
15277495a06bSColomban Wendling vStringPut (name->string, '.');
15287495a06bSColomban Wendling readToken (token);
15297495a06bSColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
15307495a06bSColomban Wendling {
15317495a06bSColomban Wendling vStringCat (name->string, token->string);
15327495a06bSColomban Wendling readToken (token);
15337495a06bSColomban Wendling }
15347495a06bSColomban Wendling }
15353a43a456SColomban Wendling }
15363a43a456SColomban Wendling
15373a43a456SColomban Wendling if (isType (token, TOKEN_OPEN_CURLY))
15383a43a456SColomban Wendling {
15393a43a456SColomban Wendling if (name)
15403a43a456SColomban Wendling makeFlexTag (name, FLEXTAG_PACKAGE);
15413a43a456SColomban Wendling parseBlock (token, name ? name->string : NULL);
15423a43a456SColomban Wendling }
15433a43a456SColomban Wendling
15443a43a456SColomban Wendling if (name)
15453a43a456SColomban Wendling deleteToken (name);
15463a43a456SColomban Wendling }
15473a43a456SColomban Wendling
parseClass(tokenInfo * const token)1548ce990805SThomas Braun static bool parseClass (tokenInfo *const token)
15493ae02089SMasatake YAMATO {
15503ae02089SMasatake YAMATO tokenInfo *const name = newToken ();
1551ce990805SThomas Braun bool saveIsClass = token->isClass;
15523ae02089SMasatake YAMATO
15533ae02089SMasatake YAMATO /*
15543ae02089SMasatake YAMATO * Variables are defined as:
15553ae02089SMasatake YAMATO * private static var lastFaultMessage:Date = new Date( 0 );
15563ae02089SMasatake YAMATO * private static var webRequests:ArrayCollection = new ArrayCollection();
15573ae02089SMasatake YAMATO */
15583ae02089SMasatake YAMATO
15593ae02089SMasatake YAMATO if ( isKeyword(token, KEYWORD_class) )
15603ae02089SMasatake YAMATO {
15613ae02089SMasatake YAMATO readToken(token);
15623ae02089SMasatake YAMATO }
15633ae02089SMasatake YAMATO
1564ce990805SThomas Braun token->isClass = true;
15653ae02089SMasatake YAMATO /* Class name */
15668bbb9d0dSColomban Wendling copyToken (name, token, true);
15673ae02089SMasatake YAMATO readToken(token);
15683ae02089SMasatake YAMATO
15693ae02089SMasatake YAMATO DebugStatement (
15703ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
15713ae02089SMasatake YAMATO , "\n parseClass start: token isClass:%d scope:%s name:%s\n"
15723ae02089SMasatake YAMATO , token->isClass
15733ae02089SMasatake YAMATO , vStringValue(token->scope)
15743ae02089SMasatake YAMATO , vStringValue(token->string)
15753ae02089SMasatake YAMATO );
15763ae02089SMasatake YAMATO );
1577bf149776SColomban Wendling
1578bf149776SColomban Wendling if (isKeyword (token, KEYWORD_extends))
1579bf149776SColomban Wendling {
1580bf149776SColomban Wendling readToken (token);
1581bf149776SColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
1582bf149776SColomban Wendling readToken (token);
1583bf149776SColomban Wendling }
1584bf149776SColomban Wendling
1585bf149776SColomban Wendling if (isKeyword (token, KEYWORD_implements))
1586bf149776SColomban Wendling {
1587bf149776SColomban Wendling do
1588bf149776SColomban Wendling {
1589bf149776SColomban Wendling readToken (token);
1590bf149776SColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
1591bf149776SColomban Wendling readToken (token);
1592bf149776SColomban Wendling }
1593bf149776SColomban Wendling while (isType (token, TOKEN_COMMA));
1594bf149776SColomban Wendling }
1595bf149776SColomban Wendling
15963ae02089SMasatake YAMATO if ( isType (token, TOKEN_OPEN_CURLY) )
15973ae02089SMasatake YAMATO {
15983ae02089SMasatake YAMATO makeClassTag (name);
15998bbb9d0dSColomban Wendling parseBlock (token, name->string);
16003ae02089SMasatake YAMATO }
16013ae02089SMasatake YAMATO
16023ae02089SMasatake YAMATO DebugStatement (
16033ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
16043ae02089SMasatake YAMATO , "\n parseClass end: token isClass:%d scope:%s name:%s\n"
16053ae02089SMasatake YAMATO , token->isClass
16063ae02089SMasatake YAMATO , vStringValue(token->scope)
16073ae02089SMasatake YAMATO , vStringValue(token->string)
16083ae02089SMasatake YAMATO );
16093ae02089SMasatake YAMATO );
16103ae02089SMasatake YAMATO token->isClass = saveIsClass;
16113ae02089SMasatake YAMATO deleteToken (name);
16123ae02089SMasatake YAMATO
1613ce990805SThomas Braun return true;
16143ae02089SMasatake YAMATO }
16153ae02089SMasatake YAMATO
parseInterface(tokenInfo * const token)1616c8580ab1SColomban Wendling static void parseInterface (tokenInfo *const token)
1617c8580ab1SColomban Wendling {
1618c8580ab1SColomban Wendling tokenInfo *const name = newToken ();
1619c8580ab1SColomban Wendling bool saveIsClass = token->isClass;
1620c8580ab1SColomban Wendling
1621c8580ab1SColomban Wendling if (isKeyword(token, KEYWORD_interface))
1622c8580ab1SColomban Wendling readToken(token);
1623c8580ab1SColomban Wendling
1624c8580ab1SColomban Wendling token->isClass = true;
1625c8580ab1SColomban Wendling /* interface name */
1626c8580ab1SColomban Wendling copyToken (name, token, true);
1627c8580ab1SColomban Wendling readToken (token);
1628c8580ab1SColomban Wendling
1629c8580ab1SColomban Wendling /* interfaces can extend multiple interfaces */
1630c8580ab1SColomban Wendling if (isKeyword (token, KEYWORD_extends))
1631c8580ab1SColomban Wendling {
1632c8580ab1SColomban Wendling do
1633c8580ab1SColomban Wendling {
1634c8580ab1SColomban Wendling readToken (token);
1635c8580ab1SColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
1636c8580ab1SColomban Wendling readToken (token);
1637c8580ab1SColomban Wendling }
1638c8580ab1SColomban Wendling while (isType (token, TOKEN_COMMA));
1639c8580ab1SColomban Wendling }
1640c8580ab1SColomban Wendling
1641c8580ab1SColomban Wendling if (isType (token, TOKEN_OPEN_CURLY))
1642c8580ab1SColomban Wendling {
1643c8580ab1SColomban Wendling makeFlexTag (name, FLEXTAG_INTERFACE);
1644c8580ab1SColomban Wendling parseBlock (token, name->string);
1645c8580ab1SColomban Wendling }
1646c8580ab1SColomban Wendling
1647c8580ab1SColomban Wendling token->isClass = saveIsClass;
1648c8580ab1SColomban Wendling deleteToken (name);
1649c8580ab1SColomban Wendling }
1650c8580ab1SColomban Wendling
parseStatement(tokenInfo * const token)1651ce990805SThomas Braun static bool parseStatement (tokenInfo *const token)
16523ae02089SMasatake YAMATO {
16533ae02089SMasatake YAMATO tokenInfo *const name = newToken ();
16543ae02089SMasatake YAMATO tokenInfo *const secondary_name = newToken ();
16553ae02089SMasatake YAMATO vString * saveScope = vStringNew ();
1656ce990805SThomas Braun bool is_public = false;
1657ce990805SThomas Braun bool is_class = false;
1658ce990805SThomas Braun bool is_terminated = true;
1659ce990805SThomas Braun bool is_global = false;
1660ce990805SThomas Braun /* bool is_prototype = false; */
16613ae02089SMasatake YAMATO vString * fulltag;
16623ae02089SMasatake YAMATO
16633ae02089SMasatake YAMATO vStringCopy (saveScope, token->scope);
16643ae02089SMasatake YAMATO DebugStatement (
16653ae02089SMasatake YAMATO debugPrintf (DEBUG_PARSE
16663ae02089SMasatake YAMATO , "\n parseStatement: token isClass:%d scope:%s name:%s\n"
16673ae02089SMasatake YAMATO , token->isClass
16683ae02089SMasatake YAMATO , vStringValue(token->scope)
16693ae02089SMasatake YAMATO , vStringValue(token->string)
16703ae02089SMasatake YAMATO );
16713ae02089SMasatake YAMATO );
16723ae02089SMasatake YAMATO /*
16733ae02089SMasatake YAMATO * Functions can be named or unnamed.
16743ae02089SMasatake YAMATO * This deals with these formats:
16753ae02089SMasatake YAMATO * Function
16763ae02089SMasatake YAMATO * validFunctionOne = function(a,b) {}
16773ae02089SMasatake YAMATO * testlib.validFunctionFive = function(a,b) {}
16783ae02089SMasatake YAMATO * var innerThree = function(a,b) {}
16793ae02089SMasatake YAMATO * var innerFour = (a,b) {}
16803ae02089SMasatake YAMATO * var D2 = secondary_fcn_name(a,b) {}
16813ae02089SMasatake YAMATO * var D3 = new Function("a", "b", "return a+b;");
16823ae02089SMasatake YAMATO * Class
16833ae02089SMasatake YAMATO * testlib.extras.ValidClassOne = function(a,b) {
16843ae02089SMasatake YAMATO * this.a = a;
16853ae02089SMasatake YAMATO * }
16863ae02089SMasatake YAMATO * Class Methods
16873ae02089SMasatake YAMATO * testlib.extras.ValidClassOne.prototype = {
16883ae02089SMasatake YAMATO * 'validMethodOne' : function(a,b) {},
16893ae02089SMasatake YAMATO * 'validMethodTwo' : function(a,b) {}
16903ae02089SMasatake YAMATO * }
16913ae02089SMasatake YAMATO * ValidClassTwo = function ()
16923ae02089SMasatake YAMATO * {
16933ae02089SMasatake YAMATO * this.validMethodThree = function() {}
16943ae02089SMasatake YAMATO * // unnamed method
16953ae02089SMasatake YAMATO * this.validMethodFour = () {}
16963ae02089SMasatake YAMATO * }
16973ae02089SMasatake YAMATO * Database.prototype.validMethodThree = Database_getTodaysDate;
16983ae02089SMasatake YAMATO */
16993ae02089SMasatake YAMATO
17006544ac44SColomban Wendling /* skip attributes */
17016544ac44SColomban Wendling while (isKeyword (token, KEYWORD_public) ||
17026544ac44SColomban Wendling isKeyword (token, KEYWORD_protected) ||
17036544ac44SColomban Wendling isKeyword (token, KEYWORD_private) ||
17046544ac44SColomban Wendling isKeyword (token, KEYWORD_override) ||
17056544ac44SColomban Wendling isKeyword (token, KEYWORD_static) ||
17066544ac44SColomban Wendling isKeyword (token, KEYWORD_internal) ||
17076544ac44SColomban Wendling isKeyword (token, KEYWORD_native) ||
1708ba44ff41SColomban Wendling isKeyword (token, KEYWORD_dynamic) ||
17096544ac44SColomban Wendling isKeyword (token, KEYWORD_final))
17106544ac44SColomban Wendling {
17113ae02089SMasatake YAMATO if (isKeyword(token, KEYWORD_public))
1712ce990805SThomas Braun is_public = true;
17133ae02089SMasatake YAMATO
17143ae02089SMasatake YAMATO readToken (token);
17153ae02089SMasatake YAMATO }
17163ae02089SMasatake YAMATO
17173ae02089SMasatake YAMATO if (isType(token, TOKEN_KEYWORD))
17183ae02089SMasatake YAMATO {
17193ae02089SMasatake YAMATO switch (token->keyword)
17203ae02089SMasatake YAMATO {
17213ae02089SMasatake YAMATO case KEYWORD_for:
17223ae02089SMasatake YAMATO case KEYWORD_while:
17233ae02089SMasatake YAMATO case KEYWORD_do:
17248bbb9d0dSColomban Wendling is_terminated = parseLoop (token);
17253ae02089SMasatake YAMATO break;
17263ae02089SMasatake YAMATO case KEYWORD_if:
17273ae02089SMasatake YAMATO case KEYWORD_else:
17283ae02089SMasatake YAMATO case KEYWORD_try:
17293ae02089SMasatake YAMATO case KEYWORD_catch:
17303ae02089SMasatake YAMATO case KEYWORD_finally:
17313ae02089SMasatake YAMATO /* Common semantics */
17323ae02089SMasatake YAMATO is_terminated = parseIf (token);
17333ae02089SMasatake YAMATO break;
17343ae02089SMasatake YAMATO case KEYWORD_switch:
17353ae02089SMasatake YAMATO parseSwitch (token);
17363ae02089SMasatake YAMATO break;
17373a43a456SColomban Wendling case KEYWORD_package:
17383a43a456SColomban Wendling parsePackage (token);
17393a43a456SColomban Wendling goto cleanUp;
17403a43a456SColomban Wendling break;
17413ae02089SMasatake YAMATO case KEYWORD_class:
17423ae02089SMasatake YAMATO parseClass (token);
174320fc7075SMasatake YAMATO goto cleanUp;
17443ae02089SMasatake YAMATO break;
1745c8580ab1SColomban Wendling case KEYWORD_interface:
1746c8580ab1SColomban Wendling parseInterface (token);
1747c8580ab1SColomban Wendling goto cleanUp;
1748c8580ab1SColomban Wendling break;
17493ae02089SMasatake YAMATO case KEYWORD_function:
17503ae02089SMasatake YAMATO parseFunction (token);
175120fc7075SMasatake YAMATO goto cleanUp;
17523ae02089SMasatake YAMATO break;
17533ae02089SMasatake YAMATO case KEYWORD_var:
175424528e6eSColomban Wendling case KEYWORD_const:
1755a14b72e8SColomban Wendling is_terminated = parseVar (token, is_public);
175620fc7075SMasatake YAMATO goto cleanUp;
17573ae02089SMasatake YAMATO break;
17583ae02089SMasatake YAMATO default:
17593ae02089SMasatake YAMATO readToken(token);
17603ae02089SMasatake YAMATO break;
17613ae02089SMasatake YAMATO }
17623ae02089SMasatake YAMATO }
17633ae02089SMasatake YAMATO
17648bbb9d0dSColomban Wendling nextVar:
17658bbb9d0dSColomban Wendling copyToken (name, token, true);
17663ae02089SMasatake YAMATO
17673ae02089SMasatake YAMATO while (! isType (token, TOKEN_CLOSE_CURLY) &&
17683ae02089SMasatake YAMATO ! isType (token, TOKEN_SEMICOLON) &&
176917d3d2f0SMasatake YAMATO ! isType (token, TOKEN_EQUAL_SIGN) &&
17708bbb9d0dSColomban Wendling ! isType (token, TOKEN_COMMA) &&
17718bbb9d0dSColomban Wendling ! isType (token, TOKEN_EOF))
17723ae02089SMasatake YAMATO {
17738bbb9d0dSColomban Wendling if (isType (token, TOKEN_OPEN_CURLY))
17748bbb9d0dSColomban Wendling parseBlock (token, NULL);
17758bbb9d0dSColomban Wendling
17763ae02089SMasatake YAMATO /* Potentially the name of the function */
17773ae02089SMasatake YAMATO if (isType (token, TOKEN_PERIOD))
17783ae02089SMasatake YAMATO {
17793ae02089SMasatake YAMATO /*
17803ae02089SMasatake YAMATO * Cannot be a global variable is it has dot references in the name
17813ae02089SMasatake YAMATO */
1782ce990805SThomas Braun is_global = false;
17838bbb9d0dSColomban Wendling /* Assume it's an assignment to a global name (e.g. a class) using
17848bbb9d0dSColomban Wendling * its fully qualified name, so strip the scope.
17858bbb9d0dSColomban Wendling * FIXME: resolve the scope so we can make more than an assumption. */
17868bbb9d0dSColomban Wendling vStringClear (token->scope);
17878bbb9d0dSColomban Wendling vStringClear (name->scope);
17883ae02089SMasatake YAMATO do
17893ae02089SMasatake YAMATO {
17903ae02089SMasatake YAMATO readToken (token);
17918bbb9d0dSColomban Wendling if (! isType(token, TOKEN_KEYWORD))
17923ae02089SMasatake YAMATO {
17933ae02089SMasatake YAMATO if ( is_class )
17943ae02089SMasatake YAMATO {
17953ae02089SMasatake YAMATO addToScope(token, name->string);
17963ae02089SMasatake YAMATO }
17973ae02089SMasatake YAMATO else
17983ae02089SMasatake YAMATO addContext (name, token);
17998bbb9d0dSColomban Wendling
18008bbb9d0dSColomban Wendling readToken (token);
18013ae02089SMasatake YAMATO }
18023ae02089SMasatake YAMATO else if ( isKeyword(token, KEYWORD_prototype) )
18033ae02089SMasatake YAMATO {
18043ae02089SMasatake YAMATO /*
18053ae02089SMasatake YAMATO * When we reach the "prototype" tag, we infer:
18063ae02089SMasatake YAMATO * "BindAgent" is a class
18073ae02089SMasatake YAMATO * "build" is a method
18083ae02089SMasatake YAMATO *
18093ae02089SMasatake YAMATO * function BindAgent( repeatableIdName, newParentIdName ) {
18103ae02089SMasatake YAMATO * }
18113ae02089SMasatake YAMATO *
18123ae02089SMasatake YAMATO * CASE 1
18133ae02089SMasatake YAMATO * Specified function name: "build"
18143ae02089SMasatake YAMATO * BindAgent.prototype.build = function( mode ) {
18153ae02089SMasatake YAMATO * ignore everything within this function
18163ae02089SMasatake YAMATO * }
18173ae02089SMasatake YAMATO *
18183ae02089SMasatake YAMATO * CASE 2
18193ae02089SMasatake YAMATO * Prototype listing
18203ae02089SMasatake YAMATO * ValidClassOne.prototype = {
18213ae02089SMasatake YAMATO * 'validMethodOne' : function(a,b) {},
18223ae02089SMasatake YAMATO * 'validMethodTwo' : function(a,b) {}
18233ae02089SMasatake YAMATO * }
18243ae02089SMasatake YAMATO *
18253ae02089SMasatake YAMATO */
18263ae02089SMasatake YAMATO makeClassTag (name);
1827ce990805SThomas Braun is_class = true;
1828ce990805SThomas Braun /* is_prototype = true; */
18293ae02089SMasatake YAMATO
18303ae02089SMasatake YAMATO /*
18313ae02089SMasatake YAMATO * There should a ".function_name" next.
18323ae02089SMasatake YAMATO */
18333ae02089SMasatake YAMATO readToken (token);
18343ae02089SMasatake YAMATO if (isType (token, TOKEN_PERIOD))
18353ae02089SMasatake YAMATO {
18363ae02089SMasatake YAMATO /*
18373ae02089SMasatake YAMATO * Handle CASE 1
18383ae02089SMasatake YAMATO */
18393ae02089SMasatake YAMATO readToken (token);
18408bbb9d0dSColomban Wendling if (! isType(token, TOKEN_KEYWORD))
18413ae02089SMasatake YAMATO {
18423ae02089SMasatake YAMATO addToScope(token, name->string);
18433ae02089SMasatake YAMATO
18443ae02089SMasatake YAMATO makeFlexTag (token, FLEXTAG_METHOD);
18453ae02089SMasatake YAMATO /*
18463ae02089SMasatake YAMATO * We can read until the end of the block / statement.
18473ae02089SMasatake YAMATO * We need to correctly parse any nested blocks, but
18483ae02089SMasatake YAMATO * we do NOT want to create any tags based on what is
18493ae02089SMasatake YAMATO * within the blocks.
18503ae02089SMasatake YAMATO */
1851ce990805SThomas Braun token->ignoreTag = true;
18523ae02089SMasatake YAMATO /*
18533ae02089SMasatake YAMATO * Find to the end of the statement
18543ae02089SMasatake YAMATO */
18558bbb9d0dSColomban Wendling findCmdTerm (token, false, false);
1856ce990805SThomas Braun token->ignoreTag = false;
1857ce990805SThomas Braun is_terminated = true;
18583ae02089SMasatake YAMATO goto cleanUp;
18593ae02089SMasatake YAMATO }
18603ae02089SMasatake YAMATO }
18613ae02089SMasatake YAMATO else if (isType (token, TOKEN_EQUAL_SIGN))
18623ae02089SMasatake YAMATO {
18633ae02089SMasatake YAMATO readToken (token);
18643ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_CURLY))
18653ae02089SMasatake YAMATO {
18663ae02089SMasatake YAMATO /*
18673ae02089SMasatake YAMATO * Handle CASE 2
18683ae02089SMasatake YAMATO *
18693ae02089SMasatake YAMATO * Creates tags for each of these class methods
18703ae02089SMasatake YAMATO * ValidClassOne.prototype = {
18713ae02089SMasatake YAMATO * 'validMethodOne' : function(a,b) {},
18723ae02089SMasatake YAMATO * 'validMethodTwo' : function(a,b) {}
18733ae02089SMasatake YAMATO * }
18743ae02089SMasatake YAMATO */
18753ae02089SMasatake YAMATO parseMethods(token, name);
18763ae02089SMasatake YAMATO /*
18773ae02089SMasatake YAMATO * Find to the end of the statement
18783ae02089SMasatake YAMATO */
18798bbb9d0dSColomban Wendling findCmdTerm (token, false, false);
1880ce990805SThomas Braun token->ignoreTag = false;
1881ce990805SThomas Braun is_terminated = true;
18823ae02089SMasatake YAMATO goto cleanUp;
18833ae02089SMasatake YAMATO }
18843ae02089SMasatake YAMATO }
18853ae02089SMasatake YAMATO }
18868bbb9d0dSColomban Wendling else
18873ae02089SMasatake YAMATO readToken (token);
18888bbb9d0dSColomban Wendling } while (isType (token, TOKEN_PERIOD));
18893ae02089SMasatake YAMATO }
18908bbb9d0dSColomban Wendling else
18918bbb9d0dSColomban Wendling readTokenFull (token, true);
18923ae02089SMasatake YAMATO
18933ae02089SMasatake YAMATO if ( isType (token, TOKEN_OPEN_PAREN) )
18948bbb9d0dSColomban Wendling skipArgumentList(token, false);
18953ae02089SMasatake YAMATO
18963ae02089SMasatake YAMATO if ( isType (token, TOKEN_COLON) )
18973ae02089SMasatake YAMATO {
18983ae02089SMasatake YAMATO /*
18993ae02089SMasatake YAMATO * Functions are of this form:
19003ae02089SMasatake YAMATO * function fname ():ReturnType {
19013ae02089SMasatake YAMATO */
19023ae02089SMasatake YAMATO readToken (token);
19031fd37dabSColomban Wendling if (isType (token, TOKEN_IDENTIFIER))
19043ae02089SMasatake YAMATO readToken (token);
19053ae02089SMasatake YAMATO }
19063ae02089SMasatake YAMATO
19073ae02089SMasatake YAMATO if ( isType (token, TOKEN_OPEN_SQUARE) )
19088bbb9d0dSColomban Wendling skipArrayList(token, false);
19093ae02089SMasatake YAMATO }
19103ae02089SMasatake YAMATO
19113ae02089SMasatake YAMATO if ( isType (token, TOKEN_CLOSE_CURLY) )
19123ae02089SMasatake YAMATO {
19133ae02089SMasatake YAMATO /*
19143ae02089SMasatake YAMATO * Reaching this section without having
19153ae02089SMasatake YAMATO * processed an open curly brace indicates
19163ae02089SMasatake YAMATO * the statement is most likely not terminated.
19173ae02089SMasatake YAMATO */
1918ce990805SThomas Braun is_terminated = false;
19193ae02089SMasatake YAMATO goto cleanUp;
19203ae02089SMasatake YAMATO }
19213ae02089SMasatake YAMATO
19228bbb9d0dSColomban Wendling if ( isType (token, TOKEN_SEMICOLON) ||
19238bbb9d0dSColomban Wendling isType (token, TOKEN_EOF) ||
19248bbb9d0dSColomban Wendling isType (token, TOKEN_COMMA) )
19253ae02089SMasatake YAMATO {
19263ae02089SMasatake YAMATO /*
19273ae02089SMasatake YAMATO * Only create variables for global scope
19283ae02089SMasatake YAMATO */
19293ae02089SMasatake YAMATO if ( token->nestLevel == 0 && is_global )
19303ae02089SMasatake YAMATO {
19313ae02089SMasatake YAMATO /*
19323ae02089SMasatake YAMATO * Handles this syntax:
19333ae02089SMasatake YAMATO * var g_var2;
19343ae02089SMasatake YAMATO */
19353ae02089SMasatake YAMATO makeFlexTag (name, FLEXTAG_VARIABLE);
19363ae02089SMasatake YAMATO }
19373ae02089SMasatake YAMATO /*
19383ae02089SMasatake YAMATO * Statement has ended.
19393ae02089SMasatake YAMATO * This deals with calls to functions, like:
19403ae02089SMasatake YAMATO * alert(..);
19413ae02089SMasatake YAMATO */
19428bbb9d0dSColomban Wendling if (isType (token, TOKEN_COMMA))
19438bbb9d0dSColomban Wendling {
19448bbb9d0dSColomban Wendling readToken (token);
19458bbb9d0dSColomban Wendling goto nextVar;
19468bbb9d0dSColomban Wendling }
19473ae02089SMasatake YAMATO goto cleanUp;
19483ae02089SMasatake YAMATO }
19493ae02089SMasatake YAMATO
19503ae02089SMasatake YAMATO if ( isType (token, TOKEN_EQUAL_SIGN) )
19513ae02089SMasatake YAMATO {
19523ae02089SMasatake YAMATO readToken (token);
19533ae02089SMasatake YAMATO
19543ae02089SMasatake YAMATO if ( isKeyword (token, KEYWORD_function) )
19553ae02089SMasatake YAMATO {
19563ae02089SMasatake YAMATO readToken (token);
19573ae02089SMasatake YAMATO
19588bbb9d0dSColomban Wendling if (! isType (token, TOKEN_KEYWORD) &&
19593ae02089SMasatake YAMATO ! isType (token, TOKEN_OPEN_PAREN))
19603ae02089SMasatake YAMATO {
19613ae02089SMasatake YAMATO /*
19623ae02089SMasatake YAMATO * Functions of this format:
19633ae02089SMasatake YAMATO * var D2A = function theAdd(a, b)
19643ae02089SMasatake YAMATO * {
19653ae02089SMasatake YAMATO * return a+b;
19663ae02089SMasatake YAMATO * }
19673ae02089SMasatake YAMATO * Are really two separate defined functions and
19683ae02089SMasatake YAMATO * can be referenced in two ways:
19693ae02089SMasatake YAMATO * alert( D2A(1,2) ); // produces 3
19703ae02089SMasatake YAMATO * alert( theAdd(1,2) ); // also produces 3
19713ae02089SMasatake YAMATO * So it must have two tags:
19723ae02089SMasatake YAMATO * D2A
19733ae02089SMasatake YAMATO * theAdd
19743ae02089SMasatake YAMATO * Save the reference to the name for later use, once
19753ae02089SMasatake YAMATO * we have established this is a valid function we will
19763ae02089SMasatake YAMATO * create the secondary reference to it.
19773ae02089SMasatake YAMATO */
19788bbb9d0dSColomban Wendling copyToken (secondary_name, token, true);
19793ae02089SMasatake YAMATO readToken (token);
19803ae02089SMasatake YAMATO }
19813ae02089SMasatake YAMATO
19823ae02089SMasatake YAMATO if ( isType (token, TOKEN_OPEN_PAREN) )
19838bbb9d0dSColomban Wendling skipArgumentList(token, false);
19843ae02089SMasatake YAMATO
19853ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_CURLY))
19863ae02089SMasatake YAMATO {
19873ae02089SMasatake YAMATO /*
19883ae02089SMasatake YAMATO * This will be either a function or a class.
19893ae02089SMasatake YAMATO * We can only determine this by checking the body
19903ae02089SMasatake YAMATO * of the function. If we find a "this." we know
19913ae02089SMasatake YAMATO * it is a class, otherwise it is a function.
19923ae02089SMasatake YAMATO */
19933ae02089SMasatake YAMATO if ( token->isClass )
19943ae02089SMasatake YAMATO {
19953ae02089SMasatake YAMATO makeFlexTag (name, FLEXTAG_METHOD);
19963ae02089SMasatake YAMATO if ( vStringLength(secondary_name->string) > 0 )
19973ae02089SMasatake YAMATO makeFunctionTag (secondary_name);
19988bbb9d0dSColomban Wendling parseBlock (token, name->string);
19993ae02089SMasatake YAMATO }
20003ae02089SMasatake YAMATO else
20013ae02089SMasatake YAMATO {
20028bbb9d0dSColomban Wendling parseBlock (token, name->string);
20033ae02089SMasatake YAMATO makeFunctionTag (name);
20043ae02089SMasatake YAMATO
20053ae02089SMasatake YAMATO if ( vStringLength(secondary_name->string) > 0 )
20063ae02089SMasatake YAMATO makeFunctionTag (secondary_name);
20073ae02089SMasatake YAMATO }
20083ae02089SMasatake YAMATO }
20093ae02089SMasatake YAMATO }
20103ae02089SMasatake YAMATO else if (isType (token, TOKEN_OPEN_PAREN))
20113ae02089SMasatake YAMATO {
20123ae02089SMasatake YAMATO /*
20133ae02089SMasatake YAMATO * Handle nameless functions
20143ae02089SMasatake YAMATO * this.method_name = () {}
20153ae02089SMasatake YAMATO */
20168bbb9d0dSColomban Wendling skipArgumentList(token, false);
20173ae02089SMasatake YAMATO
20183ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_CURLY))
20193ae02089SMasatake YAMATO {
20203ae02089SMasatake YAMATO /*
20213ae02089SMasatake YAMATO * Nameless functions are only setup as methods.
20223ae02089SMasatake YAMATO */
20233ae02089SMasatake YAMATO makeFlexTag (name, FLEXTAG_METHOD);
20248bbb9d0dSColomban Wendling parseBlock (token, name->string);
20253ae02089SMasatake YAMATO }
20263ae02089SMasatake YAMATO }
20273ae02089SMasatake YAMATO else if (isType (token, TOKEN_OPEN_CURLY))
20283ae02089SMasatake YAMATO {
20293ae02089SMasatake YAMATO /*
20303ae02089SMasatake YAMATO * Creates tags for each of these class methods
20313ae02089SMasatake YAMATO * ValidClassOne.prototype = {
20323ae02089SMasatake YAMATO * 'validMethodOne' : function(a,b) {},
20333ae02089SMasatake YAMATO * 'validMethodTwo' : function(a,b) {}
20343ae02089SMasatake YAMATO * }
20353ae02089SMasatake YAMATO */
20363ae02089SMasatake YAMATO parseMethods(token, name);
20378bbb9d0dSColomban Wendling /* Here we should be at the end of the block, on the close curly.
20388bbb9d0dSColomban Wendling * If so, read the next token not to confuse that close curly with
20398bbb9d0dSColomban Wendling * the end of the current statement. */
20403ae02089SMasatake YAMATO if (isType (token, TOKEN_CLOSE_CURLY))
20413ae02089SMasatake YAMATO {
20428bbb9d0dSColomban Wendling readTokenFull(token, true);
20438bbb9d0dSColomban Wendling is_terminated = isType (token, TOKEN_SEMICOLON);
20443ae02089SMasatake YAMATO }
20453ae02089SMasatake YAMATO }
20463ae02089SMasatake YAMATO else if (isKeyword (token, KEYWORD_new))
20473ae02089SMasatake YAMATO {
20483ae02089SMasatake YAMATO readToken (token);
20493ae02089SMasatake YAMATO if ( isKeyword (token, KEYWORD_function) ||
20503ae02089SMasatake YAMATO isKeyword (token, KEYWORD_capital_function) ||
20513ae02089SMasatake YAMATO isKeyword (token, KEYWORD_object) ||
20523ae02089SMasatake YAMATO isKeyword (token, KEYWORD_capital_object) )
20533ae02089SMasatake YAMATO {
20543ae02089SMasatake YAMATO if ( isKeyword (token, KEYWORD_object) ||
20553ae02089SMasatake YAMATO isKeyword (token, KEYWORD_capital_object) )
2056ce990805SThomas Braun is_class = true;
20573ae02089SMasatake YAMATO
20583ae02089SMasatake YAMATO readToken (token);
20593ae02089SMasatake YAMATO if ( isType (token, TOKEN_OPEN_PAREN) )
20608bbb9d0dSColomban Wendling skipArgumentList(token, true);
20613ae02089SMasatake YAMATO
20623ae02089SMasatake YAMATO if (isType (token, TOKEN_SEMICOLON))
20633ae02089SMasatake YAMATO {
20643ae02089SMasatake YAMATO if ( token->nestLevel == 0 )
20653ae02089SMasatake YAMATO {
20663ae02089SMasatake YAMATO if ( is_class )
20673ae02089SMasatake YAMATO {
20683ae02089SMasatake YAMATO makeClassTag (name);
20693ae02089SMasatake YAMATO } else {
20703ae02089SMasatake YAMATO makeFunctionTag (name);
20713ae02089SMasatake YAMATO }
20723ae02089SMasatake YAMATO }
20733ae02089SMasatake YAMATO }
20748bbb9d0dSColomban Wendling else if (isType (token, TOKEN_CLOSE_CURLY))
20758bbb9d0dSColomban Wendling is_terminated = false;
20763ae02089SMasatake YAMATO }
20773ae02089SMasatake YAMATO }
20788bbb9d0dSColomban Wendling else if (! isType (token, TOKEN_KEYWORD))
20793ae02089SMasatake YAMATO {
20803ae02089SMasatake YAMATO /*
20813ae02089SMasatake YAMATO * Only create variables for global scope
20823ae02089SMasatake YAMATO */
20833ae02089SMasatake YAMATO if ( token->nestLevel == 0 && is_global )
20843ae02089SMasatake YAMATO {
20853ae02089SMasatake YAMATO /*
20863ae02089SMasatake YAMATO * A pointer can be created to the function.
20873ae02089SMasatake YAMATO * If we recognize the function/class name ignore the variable.
20883ae02089SMasatake YAMATO * This format looks identical to a variable definition.
20893ae02089SMasatake YAMATO * A variable defined outside of a block is considered
20903ae02089SMasatake YAMATO * a global variable:
20913ae02089SMasatake YAMATO * var g_var1 = 1;
20923ae02089SMasatake YAMATO * var g_var2;
20933ae02089SMasatake YAMATO * This is not a global variable:
20943ae02089SMasatake YAMATO * var g_var = function;
20953ae02089SMasatake YAMATO * This is a global variable:
20963ae02089SMasatake YAMATO * var g_var = different_var_name;
20973ae02089SMasatake YAMATO */
20983ae02089SMasatake YAMATO fulltag = vStringNew ();
20993ae02089SMasatake YAMATO if (vStringLength (token->scope) > 0)
21003ae02089SMasatake YAMATO {
21013ae02089SMasatake YAMATO vStringCopy(fulltag, token->scope);
21021da6e7e4SMasatake YAMATO vStringPut (fulltag, '.');
21034e6bcb7bSColomban Wendling vStringCat (fulltag, token->string);
21043ae02089SMasatake YAMATO }
21053ae02089SMasatake YAMATO else
21063ae02089SMasatake YAMATO {
21073ae02089SMasatake YAMATO vStringCopy(fulltag, token->string);
21083ae02089SMasatake YAMATO }
21093ae02089SMasatake YAMATO if ( ! stringListHas(FunctionNames, vStringValue (fulltag)) &&
21103ae02089SMasatake YAMATO ! stringListHas(ClassNames, vStringValue (fulltag)) )
21113ae02089SMasatake YAMATO {
21123ae02089SMasatake YAMATO makeFlexTag (name, FLEXTAG_VARIABLE);
21133ae02089SMasatake YAMATO }
21143ae02089SMasatake YAMATO vStringDelete (fulltag);
21153ae02089SMasatake YAMATO }
21163ae02089SMasatake YAMATO }
21173ae02089SMasatake YAMATO }
21188bbb9d0dSColomban Wendling /* if we aren't already at the cmd end, advance to it and check whether
21198bbb9d0dSColomban Wendling * the statement was terminated */
21208bbb9d0dSColomban Wendling if (! isType (token, TOKEN_CLOSE_CURLY) &&
21218bbb9d0dSColomban Wendling ! isType (token, TOKEN_SEMICOLON))
21228bbb9d0dSColomban Wendling {
21233ae02089SMasatake YAMATO /*
21243ae02089SMasatake YAMATO * Statements can be optionally terminated in the case of
21253ae02089SMasatake YAMATO * statement prior to a close curly brace as in the
21263ae02089SMasatake YAMATO * document.write line below:
21273ae02089SMasatake YAMATO *
21283ae02089SMasatake YAMATO * function checkForUpdate() {
21293ae02089SMasatake YAMATO * if( 1==1 ) {
21303ae02089SMasatake YAMATO * document.write("hello from checkForUpdate<br>")
21313ae02089SMasatake YAMATO * }
21323ae02089SMasatake YAMATO * return 1;
21333ae02089SMasatake YAMATO * }
21343ae02089SMasatake YAMATO */
21358bbb9d0dSColomban Wendling is_terminated = findCmdTerm (token, true, true);
21368bbb9d0dSColomban Wendling /* if we're at a comma, try and read a second var */
21378bbb9d0dSColomban Wendling if (isType (token, TOKEN_COMMA))
21388bbb9d0dSColomban Wendling {
21398bbb9d0dSColomban Wendling readToken (token);
21408bbb9d0dSColomban Wendling goto nextVar;
21418bbb9d0dSColomban Wendling }
21428bbb9d0dSColomban Wendling }
21433ae02089SMasatake YAMATO
21443ae02089SMasatake YAMATO cleanUp:
21453ae02089SMasatake YAMATO vStringCopy(token->scope, saveScope);
21463ae02089SMasatake YAMATO deleteToken (name);
21473ae02089SMasatake YAMATO deleteToken (secondary_name);
21483ae02089SMasatake YAMATO vStringDelete(saveScope);
21493ae02089SMasatake YAMATO
21503ae02089SMasatake YAMATO return is_terminated;
21513ae02089SMasatake YAMATO }
21523ae02089SMasatake YAMATO
parseLine(tokenInfo * const token)2153ce990805SThomas Braun static bool parseLine (tokenInfo *const token)
21543ae02089SMasatake YAMATO {
2155ce990805SThomas Braun bool is_terminated = true;
21563ae02089SMasatake YAMATO /*
21573ae02089SMasatake YAMATO * Detect the common statements, if, while, for, do, ...
21583ae02089SMasatake YAMATO * This is necessary since the last statement within a block "{}"
21593ae02089SMasatake YAMATO * can be optionally terminated.
21603ae02089SMasatake YAMATO *
21613ae02089SMasatake YAMATO * If the statement is not terminated, we need to tell
21623ae02089SMasatake YAMATO * the calling routine to prevent reading an additional token
21633ae02089SMasatake YAMATO * looking for the end of the statement.
21643ae02089SMasatake YAMATO */
21653ae02089SMasatake YAMATO
21663ae02089SMasatake YAMATO if (isType(token, TOKEN_KEYWORD))
21673ae02089SMasatake YAMATO {
21683ae02089SMasatake YAMATO switch (token->keyword)
21693ae02089SMasatake YAMATO {
21703ae02089SMasatake YAMATO case KEYWORD_for:
21713ae02089SMasatake YAMATO case KEYWORD_while:
21723ae02089SMasatake YAMATO case KEYWORD_do:
21738bbb9d0dSColomban Wendling is_terminated = parseLoop (token);
21743ae02089SMasatake YAMATO break;
21753ae02089SMasatake YAMATO case KEYWORD_if:
21763ae02089SMasatake YAMATO case KEYWORD_else:
21773ae02089SMasatake YAMATO case KEYWORD_try:
21783ae02089SMasatake YAMATO case KEYWORD_catch:
21793ae02089SMasatake YAMATO case KEYWORD_finally:
21803ae02089SMasatake YAMATO /* Common semantics */
21813ae02089SMasatake YAMATO is_terminated = parseIf (token);
21823ae02089SMasatake YAMATO break;
21833ae02089SMasatake YAMATO case KEYWORD_switch:
21843ae02089SMasatake YAMATO parseSwitch (token);
21853ae02089SMasatake YAMATO break;
21868bbb9d0dSColomban Wendling case KEYWORD_return:
21878bbb9d0dSColomban Wendling readToken (token);
21888bbb9d0dSColomban Wendling is_terminated = parseLine (token);
21898bbb9d0dSColomban Wendling break;
21908bbb9d0dSColomban Wendling case KEYWORD_function:
21918bbb9d0dSColomban Wendling parseFunction (token);
21928bbb9d0dSColomban Wendling break;
219322848dcdSColomban Wendling case KEYWORD_import:
219422848dcdSColomban Wendling is_terminated = parseImport (token);
219522848dcdSColomban Wendling /* to properly support unterminated imports at top level,
219622848dcdSColomban Wendling * recurse here because parseActionScript() will *always*
219722848dcdSColomban Wendling * advance to avoid ever getting stuck. */
219822848dcdSColomban Wendling if (! is_terminated)
219922848dcdSColomban Wendling return parseLine (token);
220022848dcdSColomban Wendling break;
22013ae02089SMasatake YAMATO default:
22028bbb9d0dSColomban Wendling is_terminated = parseStatement (token);
22033ae02089SMasatake YAMATO break;
22043ae02089SMasatake YAMATO }
22053ae02089SMasatake YAMATO }
22063ae02089SMasatake YAMATO else
22073ae02089SMasatake YAMATO {
22083ae02089SMasatake YAMATO /*
22093ae02089SMasatake YAMATO * Special case where single line statements may not be
22103ae02089SMasatake YAMATO * SEMICOLON terminated. parseBlock needs to know this
22113ae02089SMasatake YAMATO * so that it does not read the next token.
22123ae02089SMasatake YAMATO */
22133ae02089SMasatake YAMATO is_terminated = parseStatement (token);
22143ae02089SMasatake YAMATO }
22153ae02089SMasatake YAMATO return is_terminated;
22163ae02089SMasatake YAMATO }
22173ae02089SMasatake YAMATO
parseCDATA(tokenInfo * const token)2218ce990805SThomas Braun static bool parseCDATA (tokenInfo *const token)
22193ae02089SMasatake YAMATO {
22203ae02089SMasatake YAMATO if (isType (token, TOKEN_LESS_THAN))
22213ae02089SMasatake YAMATO {
22223ae02089SMasatake YAMATO /*
22233ae02089SMasatake YAMATO * Handle these tags
22243ae02089SMasatake YAMATO * <![CDATA[
22253ae02089SMasatake YAMATO * ...
22263ae02089SMasatake YAMATO * ]]>
22273ae02089SMasatake YAMATO */
22283ae02089SMasatake YAMATO readToken (token);
22293ae02089SMasatake YAMATO if (isType (token, TOKEN_EXCLAMATION))
22303ae02089SMasatake YAMATO {
223155cb157dSColomban Wendling readToken (token);
223255cb157dSColomban Wendling if (isType (token, TOKEN_OPEN_SQUARE))
223355cb157dSColomban Wendling {
22343ae02089SMasatake YAMATO readToken (token);
22353ae02089SMasatake YAMATO if (isKeyword (token, KEYWORD_cdata))
22363ae02089SMasatake YAMATO {
22373ae02089SMasatake YAMATO readToken (token);
22383ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_SQUARE))
22393ae02089SMasatake YAMATO {
22409a9998e6SColomban Wendling parseActionScript (token, true);
22413ae02089SMasatake YAMATO if (isType (token, TOKEN_CLOSE_SQUARE))
22423ae02089SMasatake YAMATO {
22433ae02089SMasatake YAMATO readToken (token);
22443ae02089SMasatake YAMATO if (isType (token, TOKEN_CLOSE_SQUARE))
22453ae02089SMasatake YAMATO {
22463ae02089SMasatake YAMATO readToken (token);
22473ae02089SMasatake YAMATO }
22483ae02089SMasatake YAMATO }
22493ae02089SMasatake YAMATO }
22503ae02089SMasatake YAMATO }
225155cb157dSColomban Wendling }
22523ae02089SMasatake YAMATO }
22533ae02089SMasatake YAMATO }
22543ae02089SMasatake YAMATO else
22553ae02089SMasatake YAMATO {
22569a9998e6SColomban Wendling parseActionScript (token, false);
22573ae02089SMasatake YAMATO }
2258ce990805SThomas Braun return true;
22593ae02089SMasatake YAMATO }
22603ae02089SMasatake YAMATO
parseNamespace(tokenInfo * const token)2261ce990805SThomas Braun static bool parseNamespace (tokenInfo *const token)
22623ae02089SMasatake YAMATO {
22633ae02089SMasatake YAMATO /*
22643ae02089SMasatake YAMATO * If we have found a <, we know it is not a TOKEN_OPEN_MXML
22653ae02089SMasatake YAMATO * but it could potentially be a different namespace.
22663ae02089SMasatake YAMATO * This means it will also have a closing tag, which will
22673ae02089SMasatake YAMATO * mess up the parser if we do not properly recurse
22683ae02089SMasatake YAMATO * through these tags.
22693ae02089SMasatake YAMATO */
22703ae02089SMasatake YAMATO
22713ae02089SMasatake YAMATO if (isType (token, TOKEN_LESS_THAN))
22723ae02089SMasatake YAMATO {
22733ae02089SMasatake YAMATO readToken (token);
22743ae02089SMasatake YAMATO }
22753ae02089SMasatake YAMATO
22763ae02089SMasatake YAMATO /*
22773ae02089SMasatake YAMATO * Check if we have reached a other namespace tag
22783ae02089SMasatake YAMATO * <views:Object ... />
22793ae02089SMasatake YAMATO * or
22803ae02089SMasatake YAMATO * <views:Object ... >
22813ae02089SMasatake YAMATO * </views:Object>
22823ae02089SMasatake YAMATO */
22833ae02089SMasatake YAMATO if (isType (token, TOKEN_IDENTIFIER))
22843ae02089SMasatake YAMATO {
22853ae02089SMasatake YAMATO readToken (token);
22863ae02089SMasatake YAMATO if (isType (token, TOKEN_COLON))
22873ae02089SMasatake YAMATO {
22883ae02089SMasatake YAMATO readToken (token);
22893ae02089SMasatake YAMATO if ( ! isType (token, TOKEN_IDENTIFIER))
22903ae02089SMasatake YAMATO {
2291ce990805SThomas Braun return true;
22923ae02089SMasatake YAMATO }
22933ae02089SMasatake YAMATO }
22943ae02089SMasatake YAMATO else
22953ae02089SMasatake YAMATO {
2296ce990805SThomas Braun return true;
22973ae02089SMasatake YAMATO }
22983ae02089SMasatake YAMATO }
22993ae02089SMasatake YAMATO else
23003ae02089SMasatake YAMATO {
2301ce990805SThomas Braun return true;
23023ae02089SMasatake YAMATO }
23033ae02089SMasatake YAMATO
23043ae02089SMasatake YAMATO /*
23053ae02089SMasatake YAMATO * Confirmed we are inside a namespace tag, so
23063ae02089SMasatake YAMATO * process it until the close tag.
23073ae02089SMasatake YAMATO *
23083ae02089SMasatake YAMATO * But also check for new tags, which will either
23093ae02089SMasatake YAMATO * be recursive namespaces or MXML tags
23103ae02089SMasatake YAMATO */
23113ae02089SMasatake YAMATO do
23123ae02089SMasatake YAMATO {
23133ae02089SMasatake YAMATO if (isType (token, TOKEN_LESS_THAN))
23143ae02089SMasatake YAMATO {
23153ae02089SMasatake YAMATO parseNamespace (token);
23163ae02089SMasatake YAMATO readToken (token);
23173ae02089SMasatake YAMATO }
23183ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_MXML))
23193ae02089SMasatake YAMATO {
23203ae02089SMasatake YAMATO parseMXML (token);
23213ae02089SMasatake YAMATO }
23223ae02089SMasatake YAMATO else
23233ae02089SMasatake YAMATO {
23243ae02089SMasatake YAMATO readToken (token);
23253ae02089SMasatake YAMATO }
232617d3d2f0SMasatake YAMATO } while (! (isType (token, TOKEN_CLOSE_SGML) ||
232717d3d2f0SMasatake YAMATO isType (token, TOKEN_CLOSE_MXML) ||
232817d3d2f0SMasatake YAMATO isEOF (token)) );
2329ce990805SThomas Braun return true;
23303ae02089SMasatake YAMATO }
23313ae02089SMasatake YAMATO
parseMXML(tokenInfo * const token)2332ce990805SThomas Braun static bool parseMXML (tokenInfo *const token)
23333ae02089SMasatake YAMATO {
23343ae02089SMasatake YAMATO tokenInfo *const name = newToken ();
23353ae02089SMasatake YAMATO tokenInfo *const type = newToken ();
2336ce990805SThomas Braun bool inside_attributes = true;
23373ae02089SMasatake YAMATO /*
23383ae02089SMasatake YAMATO * Detect the common statements, if, while, for, do, ...
23393ae02089SMasatake YAMATO * This is necessary since the last statement within a block "{}"
23403ae02089SMasatake YAMATO * can be optionally terminated.
23413ae02089SMasatake YAMATO *
23423ae02089SMasatake YAMATO * If the statement is not terminated, we need to tell
23433ae02089SMasatake YAMATO * the calling routine to prevent reading an additional token
23443ae02089SMasatake YAMATO * looking for the end of the statement.
23453ae02089SMasatake YAMATO */
23463ae02089SMasatake YAMATO
23473ae02089SMasatake YAMATO readToken (token);
23483ae02089SMasatake YAMATO
23493ae02089SMasatake YAMATO if (isKeyword (token, KEYWORD_script))
23503ae02089SMasatake YAMATO {
23513ae02089SMasatake YAMATO /*
23523ae02089SMasatake YAMATO * These tags can be of this form:
23533ae02089SMasatake YAMATO * <mx:Script src="filename.as" />
23543ae02089SMasatake YAMATO */
23553ae02089SMasatake YAMATO do
23563ae02089SMasatake YAMATO {
23573ae02089SMasatake YAMATO readToken (token);
23583ae02089SMasatake YAMATO } while (! (isType (token, TOKEN_CLOSE_SGML) ||
23593ae02089SMasatake YAMATO isType (token, TOKEN_CLOSE_MXML) ||
236017d3d2f0SMasatake YAMATO isType (token, TOKEN_GREATER_THAN) ||
236117d3d2f0SMasatake YAMATO isEOF (token)) );
23623ae02089SMasatake YAMATO
23633ae02089SMasatake YAMATO if (isType (token, TOKEN_CLOSE_MXML))
23643ae02089SMasatake YAMATO {
23653ae02089SMasatake YAMATO /*
23663ae02089SMasatake YAMATO * We have found a </mx:type> tag
23673ae02089SMasatake YAMATO * Finish reading the "type" and ">"
23683ae02089SMasatake YAMATO */
23693ae02089SMasatake YAMATO readToken (token);
23703ae02089SMasatake YAMATO readToken (token);
23713ae02089SMasatake YAMATO goto cleanUp;
23723ae02089SMasatake YAMATO }
23733ae02089SMasatake YAMATO if (isType (token, TOKEN_CLOSE_SGML))
23743ae02089SMasatake YAMATO {
23753ae02089SMasatake YAMATO /*
23763ae02089SMasatake YAMATO * We have found a <mx:Script src="filename.as" />
23773ae02089SMasatake YAMATO */
23783ae02089SMasatake YAMATO goto cleanUp;
23793ae02089SMasatake YAMATO }
23803ae02089SMasatake YAMATO
23813ae02089SMasatake YAMATO /*
23823ae02089SMasatake YAMATO * This is a beginning of an embedded script.
23833ae02089SMasatake YAMATO * These typically are of this format:
23843ae02089SMasatake YAMATO * <mx:Script>
23853ae02089SMasatake YAMATO * <![CDATA[
23863ae02089SMasatake YAMATO * ... ActionScript ...
23873ae02089SMasatake YAMATO * ]]>
23883ae02089SMasatake YAMATO * </mx:Script>
23893ae02089SMasatake YAMATO */
23903ae02089SMasatake YAMATO readToken (token);
23913ae02089SMasatake YAMATO parseCDATA (token);
23923ae02089SMasatake YAMATO
23933ae02089SMasatake YAMATO readToken (token);
23943ae02089SMasatake YAMATO if (isType (token, TOKEN_CLOSE_MXML))
23953ae02089SMasatake YAMATO {
23963ae02089SMasatake YAMATO /*
23973ae02089SMasatake YAMATO * We have found a </mx:type> tag
23983ae02089SMasatake YAMATO * Finish reading the "type" and ">"
23993ae02089SMasatake YAMATO */
24003ae02089SMasatake YAMATO readToken (token);
24013ae02089SMasatake YAMATO readToken (token);
24023ae02089SMasatake YAMATO }
24033ae02089SMasatake YAMATO goto cleanUp;
24043ae02089SMasatake YAMATO }
24053ae02089SMasatake YAMATO
24068bbb9d0dSColomban Wendling copyToken (type, token, true);
24073ae02089SMasatake YAMATO
24083ae02089SMasatake YAMATO readToken (token);
24093ae02089SMasatake YAMATO do
24103ae02089SMasatake YAMATO {
24113ae02089SMasatake YAMATO if (isType (token, TOKEN_GREATER_THAN))
24123ae02089SMasatake YAMATO {
2413ce990805SThomas Braun inside_attributes = false;
24143ae02089SMasatake YAMATO }
24153ae02089SMasatake YAMATO if (isType (token, TOKEN_LESS_THAN))
24163ae02089SMasatake YAMATO {
24173ae02089SMasatake YAMATO parseNamespace (token);
24183ae02089SMasatake YAMATO readToken (token);
24193ae02089SMasatake YAMATO }
24203ae02089SMasatake YAMATO else if (isType (token, TOKEN_OPEN_MXML))
24213ae02089SMasatake YAMATO {
24223ae02089SMasatake YAMATO parseMXML (token);
24233ae02089SMasatake YAMATO readToken (token);
24243ae02089SMasatake YAMATO }
24253ae02089SMasatake YAMATO else if (inside_attributes && (isKeyword (token, KEYWORD_id) || isKeyword (token, KEYWORD_name)))
24263ae02089SMasatake YAMATO {
24273ae02089SMasatake YAMATO if (vStringLength(name->string) == 0 )
24283ae02089SMasatake YAMATO {
24293ae02089SMasatake YAMATO /*
24303ae02089SMasatake YAMATO * If we have already created the tag based on either "name"
24313ae02089SMasatake YAMATO * or "id" do not do it again.
24323ae02089SMasatake YAMATO */
24333ae02089SMasatake YAMATO readToken (token);
24343ae02089SMasatake YAMATO readToken (token);
24353ae02089SMasatake YAMATO
24368bbb9d0dSColomban Wendling copyToken (name, token, true);
24373ae02089SMasatake YAMATO addToScope (name, type->string);
24383ae02089SMasatake YAMATO makeMXTag (name);
24393ae02089SMasatake YAMATO }
24403ae02089SMasatake YAMATO else
24413ae02089SMasatake YAMATO {
24423ae02089SMasatake YAMATO readToken (token);
24433ae02089SMasatake YAMATO }
24443ae02089SMasatake YAMATO }
24453ae02089SMasatake YAMATO else
24463ae02089SMasatake YAMATO {
24473ae02089SMasatake YAMATO readToken (token);
24483ae02089SMasatake YAMATO }
244917d3d2f0SMasatake YAMATO } while (! (isType (token, TOKEN_CLOSE_SGML) ||
245017d3d2f0SMasatake YAMATO isType (token, TOKEN_CLOSE_MXML) ||
245117d3d2f0SMasatake YAMATO isEOF (token)) );
24523ae02089SMasatake YAMATO
24533ae02089SMasatake YAMATO if (isType (token, TOKEN_CLOSE_MXML))
24543ae02089SMasatake YAMATO {
24553ae02089SMasatake YAMATO /*
24563ae02089SMasatake YAMATO * We have found a </mx:type> tag
24573ae02089SMasatake YAMATO * Finish reading the "type" and ">"
24583ae02089SMasatake YAMATO */
24593ae02089SMasatake YAMATO readToken (token);
24603ae02089SMasatake YAMATO readToken (token);
24613ae02089SMasatake YAMATO }
24623ae02089SMasatake YAMATO
24633ae02089SMasatake YAMATO cleanUp:
24643ae02089SMasatake YAMATO deleteToken (name);
24653ae02089SMasatake YAMATO deleteToken (type);
2466ce990805SThomas Braun return true;
24673ae02089SMasatake YAMATO }
24683ae02089SMasatake YAMATO
parseActionScript(tokenInfo * const token,bool readNext)24699a9998e6SColomban Wendling static bool parseActionScript (tokenInfo *const token, bool readNext)
24703ae02089SMasatake YAMATO {
24718bbb9d0dSColomban Wendling LastTokenType = TOKEN_UNDEFINED;
24728bbb9d0dSColomban Wendling
24733ae02089SMasatake YAMATO do
24743ae02089SMasatake YAMATO {
24759a9998e6SColomban Wendling if (! readNext)
24769a9998e6SColomban Wendling readNext = true;
24779a9998e6SColomban Wendling else
24783ae02089SMasatake YAMATO readToken (token);
24793ae02089SMasatake YAMATO
24803ae02089SMasatake YAMATO if (isType (token, TOKEN_LESS_THAN))
24813ae02089SMasatake YAMATO {
24823ae02089SMasatake YAMATO /*
24833ae02089SMasatake YAMATO * Handle these tags
24843ae02089SMasatake YAMATO * <![CDATA[
24853ae02089SMasatake YAMATO * ...
24863ae02089SMasatake YAMATO * ]]>
24873ae02089SMasatake YAMATO */
24883ae02089SMasatake YAMATO readToken (token);
24893ae02089SMasatake YAMATO if (isType (token, TOKEN_EQUAL_SIGN))
24903ae02089SMasatake YAMATO {
24913ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_SQUARE))
24923ae02089SMasatake YAMATO {
24933ae02089SMasatake YAMATO readToken (token);
24943ae02089SMasatake YAMATO if (isKeyword (token, KEYWORD_cdata))
24953ae02089SMasatake YAMATO {
24963ae02089SMasatake YAMATO readToken (token);
24973ae02089SMasatake YAMATO }
24983ae02089SMasatake YAMATO }
24993ae02089SMasatake YAMATO }
25003ae02089SMasatake YAMATO }
25013ae02089SMasatake YAMATO if (isType (token, TOKEN_CLOSE_SQUARE))
25023ae02089SMasatake YAMATO {
25033ae02089SMasatake YAMATO /*
25043ae02089SMasatake YAMATO * Handle these tags
25053ae02089SMasatake YAMATO * <![CDATA[
25063ae02089SMasatake YAMATO * ...
25073ae02089SMasatake YAMATO * ]]>
25083ae02089SMasatake YAMATO */
25093ae02089SMasatake YAMATO readToken (token);
25103ae02089SMasatake YAMATO if (isType (token, TOKEN_CLOSE_SQUARE))
25113ae02089SMasatake YAMATO {
25123ae02089SMasatake YAMATO readToken (token);
25133ae02089SMasatake YAMATO if (isType (token, TOKEN_GREATER_THAN))
25143ae02089SMasatake YAMATO {
2515ce990805SThomas Braun return true;
25163ae02089SMasatake YAMATO }
25173ae02089SMasatake YAMATO }
25183ae02089SMasatake YAMATO }
25193ae02089SMasatake YAMATO else if (isType (token, TOKEN_CLOSE_MXML))
25203ae02089SMasatake YAMATO {
25213ae02089SMasatake YAMATO /*
25223ae02089SMasatake YAMATO * Read the Script> tags
25233ae02089SMasatake YAMATO */
25243ae02089SMasatake YAMATO readToken (token);
25253ae02089SMasatake YAMATO readToken (token);
2526ce990805SThomas Braun return true;
25273ae02089SMasatake YAMATO }
25283ae02089SMasatake YAMATO else if (isType (token, TOKEN_OPEN_MXML))
25293ae02089SMasatake YAMATO {
25303ae02089SMasatake YAMATO parseMXML (token);
25313ae02089SMasatake YAMATO }
25323ae02089SMasatake YAMATO else
25333ae02089SMasatake YAMATO {
25348bbb9d0dSColomban Wendling parseLine (token);
25353ae02089SMasatake YAMATO }
253617d3d2f0SMasatake YAMATO } while (!isEOF (token));
2537ce990805SThomas Braun return true;
25383ae02089SMasatake YAMATO }
25393ae02089SMasatake YAMATO
parseFlexFile(tokenInfo * const token)25403ae02089SMasatake YAMATO static void parseFlexFile (tokenInfo *const token)
25413ae02089SMasatake YAMATO {
25423ae02089SMasatake YAMATO do
25433ae02089SMasatake YAMATO {
25443ae02089SMasatake YAMATO readToken (token);
25453ae02089SMasatake YAMATO
25463ae02089SMasatake YAMATO if (isType (token, TOKEN_OPEN_MXML))
25473ae02089SMasatake YAMATO {
25483ae02089SMasatake YAMATO parseMXML (token);
25493ae02089SMasatake YAMATO }
25503ae02089SMasatake YAMATO else if (isType (token, TOKEN_LESS_THAN))
25513ae02089SMasatake YAMATO {
25523ae02089SMasatake YAMATO readToken (token);
25533ae02089SMasatake YAMATO if (isType (token, TOKEN_QUESTION_MARK))
25543ae02089SMasatake YAMATO {
25553ae02089SMasatake YAMATO /*
25563ae02089SMasatake YAMATO * <?xml version="1.0" encoding="utf-8"?>
25573ae02089SMasatake YAMATO */
25583ae02089SMasatake YAMATO readToken (token);
255917d3d2f0SMasatake YAMATO while (! (isType (token, TOKEN_QUESTION_MARK) || isEOF (token)))
25603ae02089SMasatake YAMATO {
25613ae02089SMasatake YAMATO readToken (token);
25623ae02089SMasatake YAMATO }
25633ae02089SMasatake YAMATO readToken (token);
25643ae02089SMasatake YAMATO }
25653ae02089SMasatake YAMATO else if (isKeyword (token, KEYWORD_NONE))
25663ae02089SMasatake YAMATO {
25673ae02089SMasatake YAMATO /*
25683ae02089SMasatake YAMATO * This is a simple XML tag, read until the closing statement
25693ae02089SMasatake YAMATO * <something .... >
25703ae02089SMasatake YAMATO * </something>
25713ae02089SMasatake YAMATO */
25723ae02089SMasatake YAMATO readToken (token);
257317d3d2f0SMasatake YAMATO while (! (isType (token, TOKEN_GREATER_THAN) || isEOF (token)))
25743ae02089SMasatake YAMATO {
25753ae02089SMasatake YAMATO readToken (token);
25763ae02089SMasatake YAMATO }
25773ae02089SMasatake YAMATO }
25783ae02089SMasatake YAMATO }
25793ae02089SMasatake YAMATO else
25803ae02089SMasatake YAMATO {
25819a9998e6SColomban Wendling parseActionScript (token, false);
25823ae02089SMasatake YAMATO }
258317d3d2f0SMasatake YAMATO } while (!isEOF (token));
25843ae02089SMasatake YAMATO }
25853ae02089SMasatake YAMATO
initialize(const langType language)25863ae02089SMasatake YAMATO static void initialize (const langType language)
25873ae02089SMasatake YAMATO {
2588158a3387SMasatake YAMATO Assert (ARRAY_SIZE (FlexKinds) == FLEXTAG_COUNT);
2589970f6116SJiří Techet Lang_flex = language;
25903ae02089SMasatake YAMATO }
25913ae02089SMasatake YAMATO
findFlexTags(void)25923ae02089SMasatake YAMATO static void findFlexTags (void)
25933ae02089SMasatake YAMATO {
25943ae02089SMasatake YAMATO tokenInfo *const token = newToken ();
25953ae02089SMasatake YAMATO
25968bbb9d0dSColomban Wendling NextToken = NULL;
25973ae02089SMasatake YAMATO ClassNames = stringListNew ();
25983ae02089SMasatake YAMATO FunctionNames = stringListNew ();
25993ae02089SMasatake YAMATO
26003ae02089SMasatake YAMATO parseFlexFile (token);
26013ae02089SMasatake YAMATO
26023ae02089SMasatake YAMATO stringListDelete (ClassNames);
26033ae02089SMasatake YAMATO stringListDelete (FunctionNames);
26043ae02089SMasatake YAMATO ClassNames = NULL;
26053ae02089SMasatake YAMATO FunctionNames = NULL;
26063ae02089SMasatake YAMATO deleteToken (token);
26073ae02089SMasatake YAMATO }
26083ae02089SMasatake YAMATO
2609137eb990SK.Takata /* Create parser definition structure */
FlexParser(void)26103ae02089SMasatake YAMATO extern parserDefinition* FlexParser (void)
26113ae02089SMasatake YAMATO {
26123ae02089SMasatake YAMATO static const char *const extensions [] = { "as", "mxml", NULL };
26133ae02089SMasatake YAMATO parserDefinition *const def = parserNew ("Flex");
26143ae02089SMasatake YAMATO def->extensions = extensions;
26153ae02089SMasatake YAMATO /*
26163ae02089SMasatake YAMATO * New definitions for parsing instead of regex
26173ae02089SMasatake YAMATO */
261809ae690fSMasatake YAMATO def->kindTable = FlexKinds;
26193db72c21SMasatake YAMATO def->kindCount = ARRAY_SIZE (FlexKinds);
26203ae02089SMasatake YAMATO def->parser = findFlexTags;
26213ae02089SMasatake YAMATO def->initialize = initialize;
2622c379c5d2SMasatake YAMATO def->keywordTable = FlexKeywordTable;
26233db72c21SMasatake YAMATO def->keywordCount = ARRAY_SIZE (FlexKeywordTable);
26243ae02089SMasatake YAMATO
26253ae02089SMasatake YAMATO return def;
26263ae02089SMasatake YAMATO }
2627