Exemple #1
0
 Token *Lexer::nextToken() {
     while(true) {
         switch(_currentChar.toAscii()) {
         case '\'': return scanCharacter();
         case '"': return scanText();
         case '(': return scan(Token::LeftParenthesis);
         case ')': return scan(Token::RightParenthesis);
         case '[': return scan(Token::LeftBracket);
         case ']': return scanRightBracket();
         case '{': return scan(Token::LeftBrace);
         case '}': return scan(Token::RightBrace);
         case ';': return scan(Token::Semicolon);
         default:
             if(isEof()) return scan(Token::Eof);
             else if(isLineComment()) consumeLineComment();
             else if(isBlockComment()) consumeBlockComment();
             else if(isNewline()) return scanNewline();
             else if(isSpace()) consumeSpaces();
             else if(isName()) return scanName();
             else if(isBackquotedName()) return scanBackquotedName();
             else if(isNumber()) return scanNumber();
             else if(isOperator()) return scanOperator();
             else throw lexerException(QString("invalid character: '%1'").arg(_currentChar));
         }
     }
 }
Exemple #2
0
    bool Scanner::scanName (char c, Parser& parser, bool& cont)
    {
        std::string name;
        name += c;

        if (!scanName (name))
            return false;

        TokenLoc loc (mLoc);
        mLoc.mLiteral.clear();

        if (name.size()>=2 && name[0]=='"' && name[name.size()-1]=='"')
        {
            name = name.substr (1, name.size()-2);
// allow keywords enclosed in ""
/// \todo optionally disable
//            cont = parser.parseName (name, loc, *this);
//            return true;
        }

        int i = 0;

        std::string lowerCase = Misc::StringUtils::lowerCase(name);

        for (; keywords[i]; ++i)
            if (lowerCase==keywords[i])
                break;

        if (keywords[i])
        {
            cont = parser.parseKeyword (i, loc, *this);
            return true;
        }

        if (mExtensions)
        {
            if (int keyword = mExtensions->searchKeyword (lowerCase))
            {
                cont = parser.parseKeyword (keyword, loc, *this);
                return true;
            }
        }

        cont = parser.parseName (name, loc, *this);

        return true;
    }
Exemple #3
0
void scanProcessingInstruction(void *data, const char *target, const char *text)
{
	Scanner* self = data;
	xsMachine* the = self->the;
	scanText(data);
	scanName(the, target, 1);
	xsVar(VALUE) = xsString((xsStringValue)text);
	xsVar(LINE) = xsInteger(XML_GetCurrentLineNumber(self->expat));
	xsVar(CHILD) = xsNewInstanceOf(xsVar(PI_PROTOTYPE));
	xsSet(xsVar(CHILD), xsID_path, xsVar(PATH));
	xsSet(xsVar(CHILD), xsID_line, xsVar(LINE));
	xsSet(xsVar(CHILD), xsID_parent, xsResult);
	xsSet(xsVar(CHILD), xsID_name, xsVar(NAME));
	xsSet(xsVar(CHILD), xsID_namespace, xsVar(NAMESPACE));
	xsSet(xsVar(CHILD), xsID_prefix, xsVar(PREFIX));
	xsSet(xsVar(CHILD), xsID_value, xsVar(VALUE));
	xsArrayCacheItem(xsVar(CHILDREN), xsVar(CHILD));
}
Exemple #4
0
    bool Scanner::scanToken (Parser& parser)
    {
        switch (mPutback)
        {
            case Putback_Special:

                mPutback = Putback_None;
                return parser.parseSpecial (mPutbackCode, mPutbackLoc, *this);

            case Putback_Integer:

                mPutback = Putback_None;
                return parser.parseInt (mPutbackInteger, mPutbackLoc, *this);

            case Putback_Float:

                mPutback = Putback_None;
                return parser.parseFloat (mPutbackFloat, mPutbackLoc, *this);

            case Putback_Name:

                mPutback = Putback_None;
                return parser.parseName (mPutbackName, mPutbackLoc, *this);

            case Putback_Keyword:

                mPutback = Putback_None;
                return parser.parseKeyword (mPutbackCode, mPutbackLoc, *this);

            case Putback_None:

                break;
        }

        char c;

        if (!get (c))
        {
            parser.parseEOF (*this);
            return false;
        }
        else if (c==';')
        {
            std::string comment;

            comment += c;

            while (get (c))
            {
                if (c=='\n')
                {
                    putback (c);
                    break;
                }
                else
                    comment += c;
            }

            TokenLoc loc (mLoc);
            mLoc.mLiteral.clear();

            return parser.parseComment (comment, loc, *this);
        }
        else if (isWhitespace (c))
        {
            mLoc.mLiteral.clear();
            return true;
        }
        else if (c==':')
        {
            // treat : as a whitespace :(
            mLoc.mLiteral.clear();
            return true;
        }
        else if (std::isalpha (c) || c=='_' || c=='"')
        {
            bool cont = false;

            if (scanName (c, parser, cont))
            {
                mLoc.mLiteral.clear();
                return cont;
            }
        }
        else if (std::isdigit (c))
        {
            bool cont = false;

            if (scanInt (c, parser, cont))
            {
                mLoc.mLiteral.clear();
                return cont;
            }
        }
        else if (c==13) // linux compatibility hack
        {
            return true;
        }
        else
        {
            bool cont = false;

            if (scanSpecial (c, parser, cont))
            {
                mLoc.mLiteral.clear();
                return cont;
            }
        }

        TokenLoc loc (mLoc);
        mLoc.mLiteral.clear();

        mErrorHandler.error ("syntax error", loc);
        throw SourceException();
    }
Exemple #5
0
    bool Scanner::scanName (char c, Parser& parser, bool& cont)
    {
        std::string name;
        name += c;

        if (!scanName (name))
            return false;

        TokenLoc loc (mLoc);
        mLoc.mLiteral.clear();

        if (name.size()>=2 && name[0]=='"' && name[name.size()-1]=='"')
        {
            name = name.substr (1, name.size()-2);
// allow keywords enclosed in ""
/// \todo optionally disable
            if (mStrictKeywords)
            {
                cont = parser.parseName (name, loc, *this);
                return true;
            }
        }

        int i = 0;

        std::string lowerCase = Misc::StringUtils::lowerCase(name);
        bool isKeyword = false;
        for (; sKeywords[i]; ++i)
            if (lowerCase==sKeywords[i])
            {
                isKeyword = true;
                break;
            }

        // Russian localization and some mods use a quirk - add newline character directly
        // to compiled bytecode via HEX-editor to implement multiline messageboxes.
        // Of course, original editor will not compile such script.
        // Allow messageboxes to bybass the "incomplete string or name" error.
        if (lowerCase == "messagebox")
            enableIgnoreNewlines();
        else if (isKeyword)
            mIgnoreNewline = false;

        if (sKeywords[i])
        {
            cont = parser.parseKeyword (i, loc, *this);
            return true;
        }

        if (mExtensions)
        {
            if (int keyword = mExtensions->searchKeyword (lowerCase))
            {
                cont = parser.parseKeyword (keyword, loc, *this);
                return true;
            }
        }

        cont = parser.parseName (name, loc, *this);

        return true;
    }
Exemple #6
0
void scanStartTag(void *data, const char *tag, const char **attributes)
{
	Scanner* self = data;
	xsMachine* the = self->the;
	const char **attribute;
	char* name;
	char* value;
	char* colon;
	scanText(data);
	xsVar(LINE) = xsInteger(XML_GetCurrentLineNumber(self->expat));
	xsVar(CHILD) = xsNewInstanceOf(xsVar(ELEMENT_PROTOTYPE));
	xsSet(xsVar(CHILD), xsID_path, xsVar(PATH));
	xsSet(xsVar(CHILD), xsID_line, xsVar(LINE));
	xsSet(xsVar(CHILD), xsID_parent, xsResult);
	if (!self->root) {
		self->root = 1;
		xsSet(xsResult, xsID_element, xsVar(CHILD));
	}
	xsArrayCacheItem(xsVar(CHILDREN), xsVar(CHILD));
	xsResult = xsVar(CHILD);
	
	xsVar(CHILDREN) = xsNewInstanceOf(xsArrayPrototype);
	xsArrayCacheBegin(xsVar(CHILDREN));
	attribute = attributes;
	while (*attribute) {
		name = (char*)*attribute;
		attribute++;
		value = (char*)*attribute;
		attribute++;
		if (c_strncmp(name, "xmlns", 5) == 0) {
			colon = name + 5;
			if (*colon == ':') {
				*colon = 0;
				xsVar(NAME) = xsString(colon + 1);
				*colon = ':';
				xsVar(PREFIX) = xsVar(XML_PREFIX);
			}
			else {
				xsVar(NAME) = xsVar(XML_PREFIX);
				xsVar(PREFIX) = xsUndefined;
			}
			xsVar(NAMESPACE) = xsVar(XML_NAMESPACE);
			xsVar(VALUE) = xsString(value);
			xsVar(CHILD) = xsNewInstanceOf(xsVar(ATTRIBUTE_PROTOTYPE));
			xsSet(xsVar(CHILD), xsID_parent, xsResult);
			xsSet(xsVar(CHILD), xsID_path, xsVar(PATH));
			xsSet(xsVar(CHILD), xsID_line, xsVar(LINE));
			xsSet(xsVar(CHILD), xsID_name, xsVar(NAME));
			xsSet(xsVar(CHILD), xsID_namespace, xsVar(NAMESPACE));
			xsSet(xsVar(CHILD), xsID_prefix, xsVar(PREFIX));
			xsSet(xsVar(CHILD), xsID_value, xsVar(VALUE));
			xsArrayCacheItem(xsVar(CHILDREN), xsVar(CHILD));
		}
	}
	xsArrayCacheEnd(xsVar(CHILDREN));
	xsSet(xsResult, xsID_xmlnsAttributes, xsVar(CHILDREN));
	
	xsVar(CHILDREN) = xsNewInstanceOf(xsArrayPrototype);
	xsArrayCacheBegin(xsVar(CHILDREN));
	attribute = attributes;
	while (*attribute) {
		name = (char*)*attribute;
		attribute++;
		value = (char*)*attribute;
		attribute++;
		if (c_strncmp(name, "xmlns", 5) != 0) {
			scanName(the, name, 0);
			xsVar(VALUE) = xsString(value);
			xsVar(CHILD) = xsNewInstanceOf(xsVar(ATTRIBUTE_PROTOTYPE));
			xsSet(xsVar(CHILD), xsID_parent, xsResult);
			xsSet(xsVar(CHILD), xsID_path, xsVar(PATH));
			xsSet(xsVar(CHILD), xsID_line, xsVar(LINE));
			xsSet(xsVar(CHILD), xsID_name, xsVar(NAME));
			xsSet(xsVar(CHILD), xsID_namespace, xsVar(NAMESPACE));
			xsSet(xsVar(CHILD), xsID_prefix, xsVar(PREFIX));
			xsSet(xsVar(CHILD), xsID_value, xsVar(VALUE));
			xsArrayCacheItem(xsVar(CHILDREN), xsVar(CHILD));
		}
	}
	xsArrayCacheEnd(xsVar(CHILDREN));
	xsSet(xsResult, xsID__attributes, xsVar(CHILDREN));

	scanName(the, tag, 1);
	xsSet(xsResult, xsID_name, xsVar(NAME));
	xsSet(xsResult, xsID_namespace, xsVar(NAMESPACE));
	xsSet(xsResult, xsID_prefix, xsVar(PREFIX));
	xsVar(CHILDREN) = xsNewInstanceOf(xsArrayPrototype);
	xsArrayCacheBegin(xsVar(CHILDREN));
	xsSet(xsResult, xsID_children, xsVar(CHILDREN));
}