Ejemplo n.º 1
0
static void parseInherit (tokenInfo *const token)
{
	Assert (isKeyword (token, KEYWORD_inherit));
	readToken (token);
	while (isType (token, TOKEN_IDENTIFIER))
	{
		parseType (token);
		if (isType (token, TOKEN_KEYWORD))
		{
			switch (token->keyword)  /* check for feature adaptation */
			{
				case KEYWORD_rename:
					parseRename (token);
				case KEYWORD_export:
				case KEYWORD_undefine:
				case KEYWORD_redefine:
				case KEYWORD_select:
					if (findKeyword (token, KEYWORD_end))
						readToken (token);
					break;

				case KEYWORD_end:
					readToken (token);
					break;

				default: break;
			}
		}
		if (isType (token, TOKEN_SEMICOLON))
			readToken (token);
	}
}
Ejemplo n.º 2
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RifEclipseInputFileTools::parseAndReadFaults(const QString& fileName, cvf::Collection<RigFault>* faults)
{
    QFile data(fileName);
    if (!data.open(QFile::ReadOnly))
    {
        return;
    }

    qint64 filePos = findKeyword(faultsKeyword, data, 0);

    while (filePos != -1)
    {
        readFaults(data, filePos, faults, nullptr);
        filePos = findKeyword(faultsKeyword, data, filePos);
    }
}
Ejemplo n.º 3
0
    std::string getVerboseTokenName(Token token) {
        const auto MaxLength = 64;
        const auto tokenText = token.text;

        switch (token.type) {
            case TokenType::Identifier: {
                Keyword keyword = findKeyword(tokenText);
                if (keyword == Keyword::None) {
                    return "identifier `" + text::truncate(tokenText, MaxLength) + "`";
                }
                return "keyword `" + tokenText.toString() + "`";
            }
            case TokenType::Integer:
            case TokenType::Hexadecimal:
            case TokenType::Binary:
                return "number `" + text::truncate(tokenText, MaxLength) + "`";
            case TokenType::String: {
                std::string truncatedText = text::truncate(tokenText, MaxLength);
                return "string \"" + text::escape(StringView(truncatedText), '\"') + "\"";
            }
            case TokenType::Character: {
                std::string truncatedText = text::truncate(tokenText, MaxLength);
                return "character '" + text::escape(StringView(truncatedText), '\'') + "'";
            }
            default:
                return getSimpleTokenName(token).toString();
        }
    }
Ejemplo n.º 4
0
static void findEiffelTags (void)
{
	tokenInfo *const token = newToken ();

	while (findKeyword (token, KEYWORD_class))
		parseClass (token);
	deleteToken (token);
}
Ejemplo n.º 5
0
static void findEiffelTags (void)
{
    tokenInfo *const token = newToken ();
    exception_t exception;

    exception = (exception_t) (setjmp (Exception));
    while (exception == ExceptionNone)
    {
        findKeyword (token, KEYWORD_class);
        parseClass (token);
    }
    deleteToken (token);
}
Ejemplo n.º 6
0
CommandType commandType(const char* s)
{
    int found = findKeyword(s);
    if (found != -1)
    {
        return keywords[found].cmdType;
    }
    else
    {
        error(ET_UNEXPECTED_TOKEN);
        return 0;
    }
}
Ejemplo n.º 7
0
static void parseGeneric (tokenInfo *const token, boolean declaration __unused__)
{
    unsigned int depth = 0;
#ifdef TYPE_REFERENCE_TOOL
    boolean constraint = FALSE;
#endif
    Assert (isType (token, TOKEN_OPEN_BRACKET));
    do
    {
        if (isType (token, TOKEN_OPEN_BRACKET))
            ++depth;
        else if (isType (token, TOKEN_CLOSE_BRACKET))
            --depth;
#ifdef TYPE_REFERENCE_TOOL
        else if (declaration)
        {
            if (depth == 1)
            {
                if (isType (token, TOKEN_CONSTRAINT))
                    constraint = TRUE;
                else if (isKeyword (token, KEYWORD_create))
                    findKeyword (token, KEYWORD_end);
                else if (isType (token, TOKEN_IDENTIFIER))
                {
                    if (constraint)
                        reportType (token);
                    else
                        addGenericName (token);
                    constraint = FALSE;
                }
            }
            else if (isKeyword (token, KEYWORD_like))
                readToken (token);
            else if (isType (token, TOKEN_IDENTIFIER))
                reportType (token);
        }
        else
        {
            if (isType (token, TOKEN_OPEN_BRACKET))
                ++depth;
            else if (isType (token, TOKEN_IDENTIFIER))
                reportType (token);
            else if (isKeyword (token, KEYWORD_like))
                readToken (token);
        }
#endif
        readToken (token);
    } while (depth > 0);
}
Ejemplo n.º 8
0
void CppSyntaxHighlighter::highlightKeyword(int currentPos, const QString &buffer)
{
    if (buffer.isEmpty())
        return;

    if (buffer.at(0) == QLatin1Char('Q')) {
        setFormat(currentPos - buffer.length(), buffer.length(), typeFormat);
    } else {
        const Keyword *kw = findKeyword(buffer);
        if (kw->name) {
            if (kw->type == NormalKeyword)
                setFormat(currentPos - buffer.length(), buffer.length(), keywordFormat);
            else if (kw->type == TypeKeyword)
                setFormat(currentPos - buffer.length(), buffer.length(), typeFormat);
        }
    }
}
Ejemplo n.º 9
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RifEclipseInputFileTools::readFaultsInGridSection(const QString& fileName, cvf::Collection<RigFault>* faults, std::vector<QString>* filenamesWithFaults, const QString& faultIncludeFileAbsolutePathPrefix)
{
    QFile data(fileName);
    if (!data.open(QFile::ReadOnly))
    {
        return;
    }

    // Search for keyword grid
    qint64 gridPos = findKeyword(gridKeyword, data, 0);
    if (gridPos < 0)
    {
        return;
    }

    bool isEditKeywordDetected = false;

    std::vector< std::pair<QString, QString> > pathAliasDefinitions;
    parseAndReadPathAliasKeyword(fileName, &pathAliasDefinitions);

    readFaultsAndParseIncludeStatementsRecursively(data, gridPos, pathAliasDefinitions, faults, filenamesWithFaults, &isEditKeywordDetected, faultIncludeFileAbsolutePathPrefix);
}
Ejemplo n.º 10
0
string Room::lookAt(string objName){
	//This method is used if the user types the "look <noun>" command.  <noun> can be a valid keyword.

	if ( findKeyword(objName) ){
		return "\n" + getExtDesc() + "\n";
	}


	for (auto & door : doorList) {
		if ( door->getLeadsTo()->findKeyword(objName) || door->findKeyword(objName)){
			return "\n" + door->getDesc() + "\n";
		}
	}

	for (auto & npc : npcList) {
		if ( npc->searchKeyword(objName)){
			return "\n" + npc->getDescription() + "\n";
		}
	}

	for (auto & user : userList) {
		if (0 == strcasecmp(objName.c_str(), user->getUserName().c_str())){
			return "\n" + user->getDescription() + "\n";
		}
	}

	
	for (auto &item : itemList){
		if(item->searchKeyword(objName)){
			return "\n" + item->getShortDesc() + "\n";
		}
	}
	

	return "\""+objName+"\""+" not found!\n";

}
Ejemplo n.º 11
0
vector<string> Room::getObjKeywords(string objName){ //Gets a List of an Object's Keywords.
	if ( findKeyword(objName) ){
		return getKeywords();
	}
	for (auto & door : doorList) {
		if ( door->findKeyword(objName) || door->getLeadsTo()->findKeyword(objName)){
			return door->getKeywords();
		}
	}
	for (auto & npc : npcList) {
		if ( npc->searchKeyword(objName)){
			return npc->getKeyword();
		}
	}

	for (auto & item : itemList) {
		if ( item->searchKeyword(objName)){
			return item->getKeyword();
		}
	}
	vector<string> result;
	result.push_back("Object not found!");
	return result;
}
Ejemplo n.º 12
0
static void parseRename (tokenInfo *const token)
{
    do {
        readToken (token);
        if (readFeatureName (token))
        {
            readToken (token);
            if (isKeyword (token, KEYWORD_as))
            {
                readToken (token);
                if (readFeatureName (token))
                {
#ifndef TYPE_REFERENCE_TOOL
                    makeEiffelFeatureTag (token);  /* renamed feature */
#endif
                    readToken (token);
                }
            }
        }
    } while (isType (token, TOKEN_COMMA));

    findKeyword (token, KEYWORD_end);
    readToken (token);
}
Ejemplo n.º 13
0
    Token Scanner::next() {
        std::string text;
        while (true) {
            while (position < buffer.length()) {
                char c = buffer[position];
                switch (state) {
                    case State::Start:
                        switch (c) {
                            case '0':
                                state = State::LeadingZero;
                                text += c;
                                break;
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                state = State::IntegerDigits;
                                text += c;
                                break;
                            case '_':
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                            case 'g':
                            case 'h':
                            case 'i':
                            case 'j':
                            case 'k':
                            case 'l':
                            case 'm':
                            case 'n':
                            case 'o':
                            case 'p':
                            case 'q':
                            case 'r':
                            case 's':
                            case 't':
                            case 'u':
                            case 'v':
                            case 'w':
                            case 'x':
                            case 'y':
                            case 'z':
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                            case 'G':
                            case 'H':
                            case 'I':
                            case 'J':
                            case 'K':
                            case 'L':
                            case 'M':
                            case 'N':
                            case 'O':
                            case 'P':
                            case 'Q':
                            case 'R':
                            case 'S':
                            case 'T':
                            case 'U':
                            case 'V':
                            case 'W':
                            case 'X':
                            case 'Y':
                            case 'Z':
                                state = State::Identifier;
                                text += c;
                                break;
                            case '\'': case '\"':
                                terminator = c;
                                state = State::String;
                                break;
                            case ' ': case '\t': case '\r': case '\n': break;
                            case ':': position++; return Token(TokenType::Colon);
                            case ',': position++; return Token(TokenType::Comma);
                            case '.': state = State::Dot; break;
                            case '(': position++; return Token(TokenType::LeftParenthesis);
                            case ')': position++; return Token(TokenType::RightParenthesis);
                            case '[': position++; return Token(TokenType::LeftBracket);
                            case ']': position++; return Token(TokenType::RightBracket);
                            case '{': position++; return Token(TokenType::LeftBrace);
                            case '}': position++; return Token(TokenType::RightBrace);
                            case ';': position++; return Token(TokenType::Semicolon);
                            case '#': state = State::Hash; break;
                            case '|': state = State::Bar; break;
                            case '*': state = State::Asterisk; break;
                            case '%': state = State::Percent; break;
                            case '@': position++; return Token(TokenType::At);
                            case '&': state = State::Ampersand; break;
                            case '^': state = State::Caret; break;
                            case '!': state = State::Exclamation; break;
                            case '`': position++; return Token(TokenType::Backtick);
                            case '~': position++; return Token(TokenType::Tilde);
                            case '+': state = State::Plus; break;
                            case '-': state = State::Minus; break;
                            case '/': state = State::Slash; break;
                            case '=': state = State::Equals; break;
                            case '<': state = State::LessThan; break;
                            case '>': state = State::GreaterThan; break;
                            case '$': position++; return Token(TokenType::Dollar);
                            default:
                                report->error("unrecognized character `\\" + std::string(1, c) + "` found", location);
                                break;
                        }
                        break;
                    case State::Identifier:
                        switch (c) {
                            case '_':
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                            case 'g':
                            case 'h':
                            case 'i':
                            case 'j':
                            case 'k':
                            case 'l':
                            case 'm':
                            case 'n':
                            case 'o':
                            case 'p':
                            case 'q':
                            case 'r':
                            case 's':
                            case 't':
                            case 'u':
                            case 'v':
                            case 'w':
                            case 'x':
                            case 'y':
                            case 'z':
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                            case 'G':
                            case 'H':
                            case 'I':
                            case 'J':
                            case 'K':
                            case 'L':
                            case 'M':
                            case 'N':
                            case 'O':
                            case 'P':
                            case 'Q':
                            case 'R':
                            case 'S':
                            case 'T':
                            case 'U':
                            case 'V':
                            case 'W':
                            case 'X':
                            case 'Y':
                            case 'Z':
                                text += c;
                                break;
                            default: {
                                state = State::Start;
                                const auto internedText = stringPool->intern(text);
                                return Token(TokenType::Identifier, findKeyword(internedText), internedText);
                            }
                        }
                        break;
                    case State::String:
                        if (c == terminator) {
                            position++;
                            state = State::Start;
                            switch (terminator) {
                                case '\'':
                                    if (text.size() != 1) {
                                        report->error("invalid character literal '" + text::escape(StringView(text), '\'') + "' (character literals must be exactly one character)", location);
                                        return Token(TokenType::Character, StringView(ErrorText));
                                    } else {
                                        return Token(TokenType::Character, stringPool->intern(text));
                                    }
                                default: return Token(TokenType::String, stringPool->intern(text));
                            }
                        } else switch (c) {
                            case '\\':
                                state = State::StringEscape;
                                break;
                            default:
                                text += c;
                                break;
                        }
                        break;
                    case State::StringEscape:
                        state = State::String;
                        switch (c) {
                            case '\"': case '\'': case '\\':
                                text += c;
                                break;
                            case 't': text += '\t'; break;
                            case 'r': text += '\r'; break;
                            case 'n': text += '\n'; break;
                            case 'f': text += '\f'; break;
                            case 'b': text += '\b'; break;
                            case 'a': text += '\a'; break;
                            case '0': text += '\0'; break;
                            case 'x':
                                state = State::HexEscapeFirstDigit;
                                break;
                            default:
                                report->error("invalid escape sequence `\\" + std::string(1, c) + "` in quoted literal", location);
                                break;
                        }
                        break;
                    case State::HexEscapeFirstDigit: {
                        state = State::HexEscapeSecondDigit;
                        switch (c) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                intermediateCharCode = static_cast<std::uint8_t>(c - '0') << 4;
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                intermediateCharCode = static_cast<std::uint8_t>(c - 'a' + 10) << 4;
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                intermediateCharCode = static_cast<std::uint8_t>(c - 'A' + 10) << 4;
                                break;
                            default:
                                state = State::String;
                                report->error("hex escape `\\x` contains illegal character `" + std::string(1, c) + "`", location);
                                break;
                        }
                        break;
                    }
                    case State::HexEscapeSecondDigit: {
                        state = State::String;
                        switch (c) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                text += static_cast<char>(intermediateCharCode | static_cast<std::uint8_t>(c - '0'));
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                text += static_cast<char>(intermediateCharCode | static_cast<std::uint8_t>(c - 'a' + 10));
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                text += static_cast<char>(intermediateCharCode | static_cast<std::uint8_t>(c - 'A' + 10));
                                break;
                            default:
                                state = State::String;
                                report->error("hex escape `\\x` contains illegal character `" + std::string(1, c) + "`", location);
                                break;
                        }
                        break;
                    }
                    case State::LeadingZero:
                        switch (c) {
                            case '_':
                                state = State::IntegerDigits;
                                break;
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                state = State::IntegerDigits;
                                text += c;
                                break;
                            case 'x': state = State::HexadecimalDigits; text += c; break;
                            case 'b': state = State::BinaryDigits; text += c; break;
                            case 'o': state = State::OctalDigits; text += c; break;
                            case 'u': case 'i':
                                text += c;
                                baseTokenType = TokenType::Integer;
                                state = State::LiteralSuffix;
                                break;
                            default:
                                state = State::Start;
                                return Token(TokenType::Integer, stringPool->intern(text));
                        }
                        break;
                    case State::IntegerDigits:
                        switch (c) {
                            case '_':
                                break;
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                text += c;
                                break;
                            case 'u': case 'i':
                                text += c;
                                baseTokenType = TokenType::Integer;
                                state = State::LiteralSuffix;
                                break;
                            default:
                                state = State::Start;
                                return Token(TokenType::Integer, stringPool->intern(text));
                        }
                        break;
                    case State::HexadecimalDigits:
                        switch (c) {
                            case '_':
                                break;
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                text += c;
                                break;
                            case 'u': case 'i':
                                text += c;
                                baseTokenType = TokenType::Hexadecimal;
                                state = State::LiteralSuffix;
                                break;
                            default:
                                state = State::Start;
                                return Token(TokenType::Hexadecimal, stringPool->intern(text));
                        }
                        break;
                    case State::OctalDigits:
                        switch (c) {
                            case '_':
                                break;
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                                text += c;
                                break;
                            case 'u': case 'i':
                                text += c;
                                baseTokenType = TokenType::Octal;
                                state = State::LiteralSuffix;
                                break;
                            default:
                                state = State::Start;
                                return Token(TokenType::Octal, stringPool->intern(text));
                        }
                        break;
                    case State::BinaryDigits:
                        switch (c) {
                            case '_':
                                break;
                            case '0': case '1':
                                text += c;
                                break;
                            case 'u': case 'i':
                                text += c;
                                baseTokenType = TokenType::Binary;
                                state = State::LiteralSuffix;
                                break;
                            default:
                                state = State::Start;
                                return Token(TokenType::Binary, stringPool->intern(text));
                        }
                        break;
                    case State::LiteralSuffix:
                        switch (c) {
                            case '_':
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                            case 'g':
                            case 'h':
                            case 'i':
                            case 'j':
                            case 'k':
                            case 'l':
                            case 'm':
                            case 'n':
                            case 'o':
                            case 'p':
                            case 'q':
                            case 'r':
                            case 's':
                            case 't':
                            case 'u':
                            case 'v':
                            case 'w':
                            case 'x':
                            case 'y':
                            case 'z':
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                            case 'G':
                            case 'H':
                            case 'I':
                            case 'J':
                            case 'K':
                            case 'L':
                            case 'M':
                            case 'N':
                            case 'O':
                            case 'P':
                            case 'Q':
                            case 'R':
                            case 'S':
                            case 'T':
                            case 'U':
                            case 'V':
                            case 'W':
                            case 'X':
                            case 'Y':
                            case 'Z':
                                text += c;
                                break;
                            default: {
                                state = State::Start;
                                return Token(baseTokenType, Keyword::None, stringPool->intern(text));
                            }
                        }
                        break;
                    case State::Exclamation:
                        state = State::Start;
                        switch (c) {
                            case '=': position++; return Token(TokenType::ExclamationEquals);
                            default: return Token(TokenType::Exclamation);
                        }
                        break;
                    case State::Plus:
                        state = State::Start;
                        switch (c) {
                            case '#': state = State::PlusHash; break;
                            case '+': position++; return Token(TokenType::DoublePlus);
                            case '=': position++; return Token(TokenType::PlusEquals);
                            default: return Token(TokenType::Plus);
                        }
                        break;
                    case State::PlusHash:
                        state = State::Start;
                        switch (c) {
                            case '=': position++; return Token(TokenType::PlusHashEquals);
                            default: return Token(TokenType::PlusHash);
                        }
                        break;
                    case State::Minus:
                        state = State::Start;
                        switch (c) {
                            case '#': state = State::MinusHash; break;
                            case '-': position++; return Token(TokenType::DoubleMinus);
                            case '=': position++; return Token(TokenType::MinusEquals);
                            case '0':
                                state = State::LeadingZero;
                                text += '-';
                                text += c;
                                break;
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                state = State::IntegerDigits;
                                text += '-';
                                text += c;
                                break;
                            default: return Token(TokenType::Minus);
                        }
                        break;
                    case State::MinusHash:
                        state = State::Start;
                        switch (c) {
                            case '=': position++; return Token(TokenType::MinusHashEquals);
                            default: return Token(TokenType::MinusHash);
                        }
                        break;
                    case State::Asterisk:
                        state = State::Start;
                        switch (c) {
                            case '=': position++; return Token(TokenType::AsteriskEquals);
                            default: return Token(TokenType::Asterisk);
                        }
                        break;
                    case State::Percent:
                        state = State::Start;
                        switch (c) {
                            case '=': position++; return Token(TokenType::PercentEquals);
                            default: return Token(TokenType::Percent);
                        }
                        break;
                    case State::Slash:
                        state = State::Start;
                        switch (c) {
                            case '/':
                                state = State::DoubleSlashComment;
                                break;
                            case '*':
                                state = State::SlashStarComment;
                                commentStartLocation.line = location.line;
                                break;
                            case '=': position++; return Token(TokenType::SlashEquals);
                            default:
                                return Token(TokenType::Slash);
                        }
                        break;
                    case State::DoubleSlashComment: break;
                    case State::SlashStarComment:
                        switch (c) {
                            case '*': state = State::SlashStarCommentStar;
                            default: break;
                        }
                        break;
                    case State::SlashStarCommentStar:
                        switch (c) {
                            case '/': state = State::Start; break;
                            default: state = State::SlashStarComment; break;
                        }
                        break;
                    case State::Equals:
                        state = State::Start;
                        switch (c) {
                            case '=': position++; return Token(TokenType::DoubleEquals);
                            default: return Token(TokenType::Equals);
                        }
                        break;
                    case State::Ampersand:
                        state = State::Start;
                        switch (c) {
                            case '&': position++; return Token(TokenType::DoubleAmpersand);
                            case '=': position++; return Token(TokenType::AmpersandEquals);
                            default: return Token(TokenType::Ampersand);
                        }
                        break;
                    case State::Bar:
                        state = State::Start;
                        switch (c) {
                            case '|': position++; return Token(TokenType::DoubleBar);
                            case '=': position++; return Token(TokenType::BarEquals);
                            default: return Token(TokenType::Bar);
                        }
                        break;
                    case State::Caret:
                        state = State::Start;
                        switch (c) {
                            case '=': position++; return Token(TokenType::CaretEquals);
                            default: return Token(TokenType::Caret);
                        }
                        break;
                    case State::LessThan:
                        state = State::Start;
                        switch (c) {
                            case '<': state = State::DoubleLessThan; break;
                            case '=': position++; return Token(TokenType::LessThanEquals);
                            case ':': position++; return Token(TokenType::LessColon);
                            default: return Token(TokenType::LessThan);
                        }
                        break;
                    case State::DoubleLessThan:
                        state = State::Start;
                        switch (c) {
                            case '<': state = State::TripleLessThan; break;
                            case '=': position++; return Token(TokenType::DoubleLessThanEquals);
                            default: return Token(TokenType::DoubleLessThan);
                        }
                        break;
                    case State::TripleLessThan:
                        state = State::Start;
                        switch (c) {
                            case '<': state = State::QuadrupleLessThan; break;
                            case '=': position++; return Token(TokenType::TripleLessThanEquals);
                            default: return Token(TokenType::TripleLessThan);
                        }
                        break;
                    case State::QuadrupleLessThan:
                        state = State::Start;
                        switch (c) {
                            case '#': state = State::QuadrupleLessThanHash; break;
                            case '=': position++; return Token(TokenType::QuadrupleLessThanEquals);
                            default: return Token(TokenType::QuadrupleLessThan);
                        }
                        break;
                    case State::QuadrupleLessThanHash:
                        state = State::Start;
                        switch (c) {                            
                            case '=': position++; return Token(TokenType::QuadrupleLessThanHashEquals);
                            default: return Token(TokenType::QuadrupleLessThanHash);
                        }
                        break;
                    case State::GreaterThan:
                        state = State::Start;
                        switch (c) {
                            case '>': state = State::DoubleGreaterThan; break;
                            case '=': position++; return Token(TokenType::GreaterThanEquals);
                            case ':': position++; return Token(TokenType::GreaterColon);
                            default: return Token(TokenType::GreaterThan);
                        }
                        break;
                    case State::DoubleGreaterThan:
                        state = State::Start;
                        switch (c) {
                            case '>': state = State::TripleGreaterThan; break;
                            case '=': position++; return Token(TokenType::DoubleGreaterThanEquals);
                            default: return Token(TokenType::DoubleGreaterThan);
                        }
                        break;
                    case State::TripleGreaterThan:
                        state = State::Start;
                        switch (c) {
                            case '>': state = State::QuadrupleGreaterThan; break;
                            case '=': position++; return Token(TokenType::TripleGreaterThanEquals);
                            default: return Token(TokenType::TripleGreaterThan);
                        }
                        break;
                    case State::QuadrupleGreaterThan:
                        state = State::Start;
                        switch (c) {
                            case '#': state = State::QuadrupleGreaterThanHash; break;
                            case '=': position++; return Token(TokenType::QuadrupleGreaterThanEquals);
                            default: return Token(TokenType::QuadrupleGreaterThan);
                        }
                        break;
                    case State::QuadrupleGreaterThanHash:
                        state = State::Start;
                        switch (c) {                            
                            case '=': position++; return Token(TokenType::QuadrupleGreaterThanHashEquals);
                            default: return Token(TokenType::QuadrupleGreaterThanHash);
                        }
                        break;
                    case State::Dot:
                        state = State::Start;
                        switch (c) {
                            case '.': state = State::DoubleDot; break;
                            default: return Token(TokenType::Dot);
                        }
                        break;
                    case State::DoubleDot:
                        state = State::Start;
                        switch (c) {
                            case '.': position++; return Token(TokenType::DotDotDot);
                            default: return Token(TokenType::DotDot);
                        }
                        break;
                    case State::Hash:
                        state = State::Start;
                        switch (c) {
                            case '[': position++; return Token(TokenType::HashBracket);
                            default: return Token(TokenType::Hash);
                        }
                        break;
                }
                position++;
            }

            if (reader && reader->isOpen() && reader->readLine(buffer)) {
                // Special handling in states for end-of-line.
                switch (state) {
                    case State::DoubleSlashComment:
                        state = State::Start;
                        break;
                    case State::String:
                        state = State::Start;
                        report->error("expected closing quote `" + std::string(1, terminator) + "`, but got end-of-line", location);
                        break;
                    case State::StringEscape:
                        state = State::Start;
                        report->error("expected string escape sequence, but got end-of-line", location);
                        break;
                    default:
                        break;
                }
                position = 0;
                location.line++;
            }
            else {
                // End-of-file.
                switch (state) {
                    case State::Identifier: {
                        state = State::Start;
                        const auto internedText = stringPool->intern(text);
                        return Token(TokenType::Identifier, findKeyword(internedText), internedText);
                    }
                    case State::LeadingZero:
                    case State::IntegerDigits:
                        state = State::Start;
                        return Token(TokenType::Integer, stringPool->intern(text));
                    case State::HexadecimalDigits:
                        state = State::Start;
                        return Token(TokenType::Hexadecimal, stringPool->intern(text));
                    case State::BinaryDigits:
                        state = State::Start;
                        return Token(TokenType::Binary, stringPool->intern(text));
                    case State::String:
                        state = State::Start;
                        report->error("expected closing quote `" + std::string(1, terminator) + "`, but got end-of-file", location);
                        break;
                    case State::StringEscape:
                        state = State::Start;
                        report->error("expected string escape sequence, but got end-of-file", location);
                        break;
                    case State::SlashStarComment:
                        report->error("expected `*/` to close comment `/*`, but got end-of-file", location, ReportErrorFlags(ReportErrorFlagType::Continued));
                        report->error("comment `/*` started here", commentStartLocation);
                        break;
                    default:
                        break;
                }
                return Token(TokenType::EndOfFile);
            }
        }
        return Token(TokenType::EndOfFile);
    }
Ejemplo n.º 14
0
int isKeyword (const char *s)
{
    return (findKeyword(s) != -1);
}
Ejemplo n.º 15
0
/**
 * process the character at the current index in a switch block.
 *
 * @param line          a reference to the line to indent.
 * @param index         the current line index.
 * @return              the new line index.
 */
size_t ASEnhancer::processSwitchBlock(string& line, size_t index)
{
	size_t i = index;
	bool isPotentialKeyword = isCharPotentialHeader(line, i);

	if (line[i] == '{')
	{
		sw.switchBracketCount++;
		if (lookingForCaseBracket)                      // if 1st after case statement
		{
			sw.unindentCase = true;                     // unindenting this case
			sw.unindentDepth++;
			lookingForCaseBracket = false;              // not looking now
		}
		return i;
	}
	lookingForCaseBracket = false;                      // no opening bracket, don't indent

	if (line[i] == '}')                                 // if close bracket
	{
		sw.switchBracketCount--;
		assert(sw.switchBracketCount <= bracketCount);
		if (sw.switchBracketCount == 0)                 // if end of switch statement
		{
			int lineUnindent = sw.unindentDepth;
			if (line.find_first_not_of(" \t") == i
			        && switchStack.size() > 0)
				lineUnindent = switchStack[switchStack.size()-1].unindentDepth;
			if (shouldIndentLine)
			{
				if (lineUnindent > 0)
					i -= unindentLine(line, lineUnindent);
				shouldIndentLine = false;
			}
			switchDepth--;
			sw = switchStack.back();
			switchStack.pop_back();
		}
		return i;
	}

	if (isPotentialKeyword
	        && (findKeyword(line, i, "case") || findKeyword(line, i, "default")))
	{
		if (sw.unindentCase)					// if unindented last case
		{
			sw.unindentCase = false;			// stop unindenting previous case
			sw.unindentDepth--;
		}

		i = findCaseColon(line, i);

		i++;
		for (; i < line.length(); i++)			// bypass whitespace
		{
			if (!isWhiteSpace(line[i]))
				break;
		}
		if (i < line.length())
		{
			if (line[i] == '{')
			{
				bracketCount++;
				sw.switchBracketCount++;
				if (!isOneLineBlockReached(line, i))
					unindentNextLine = true;
				return i;
			}
		}
		lookingForCaseBracket = true;
		i--;									// need to process this char
		return i;
	}
	if (isPotentialKeyword)
	{
		string name = getCurrentWord(line, i);          // bypass the entire name
		i += name.length() - 1;
	}
	return i;
}
Ejemplo n.º 16
0
/**
 * additional formatting for line of source code.
 * every line of source code in a source code file should be sent
 *     one after the other to this function.
 * indents event tables
 * unindents the case blocks
 *
 * @param line       the original formatted line will be updated if necessary.
 */
void ASEnhancer::enhance(string& line, bool isInPreprocessor, bool isInSQL)
{
	bool isSpecialChar = false;			// is a backslash escape character
	shouldIndentLine = true;
	lineNumber++;

	// check for beginning of event table
	if (nextLineIsEventIndent)
	{
		isInEventTable = true;
		nextLineIsEventIndent = false;
	}

	// check for beginning of SQL declare section
	if (nextLineIsDeclareIndent)
	{
		isInDeclareSection = true;
		nextLineIsDeclareIndent = false;
	}

	if (line.length() == 0
	        && ! isInEventTable
	        && ! isInDeclareSection
	        && ! emptyLineFill)
		return;

	// test for unindent on attached brackets
	if (unindentNextLine)
	{
		sw.unindentDepth++;
		sw.unindentCase = true;
		unindentNextLine = false;
	}

	// parse characters in the current line.

	for (size_t i = 0; i < line.length(); i++)
	{
		char ch = line[i];

		// bypass whitespace
		if (isWhiteSpace(ch))
			continue;

		// handle special characters (i.e. backslash+character such as \n, \t, ...)
		if (isSpecialChar)
		{
			isSpecialChar = false;
			continue;
		}
		if (!(isInComment) && line.compare(i, 2, "\\\\") == 0)
		{
			i++;
			continue;
		}
		if (!(isInComment) && ch == '\\')
		{
			isSpecialChar = true;
			continue;
		}

		// handle quotes (such as 'x' and "Hello Dolly")
		if (!isInComment && (ch == '"' || ch == '\''))
		{
			if (!isInQuote)
			{
				quoteChar = ch;
				isInQuote = true;
			}
			else if (quoteChar == ch)
			{
				isInQuote = false;
				continue;
			}
		}

		if (isInQuote)
			continue;

		// handle comments

		if (!(isInComment) && line.compare(i, 2, "//") == 0)
		{
			// check for windows line markers
			if (line.compare(i + 2, 1, "\xf0") > 0)
				lineNumber--;
			break;                 // finished with the line
		}
		else if (!(isInComment) && line.compare(i, 2, "/*") == 0)
		{
			isInComment = true;
			i++;
			continue;
		}
		else if ((isInComment) && line.compare(i, 2, "*/") == 0)
		{
			isInComment = false;
			i++;
			continue;
		}

		if (isInComment)
			continue;

		// if we have reached this far then we are NOT in a comment or string of special characters

		if (line[i] == '{')
			bracketCount++;

		if (line[i] == '}')
			bracketCount--;

		bool isPotentialKeyword = isCharPotentialHeader(line, i);

		// ----------------  wxWidgets and MFC macros  ----------------------------------

		if (isPotentialKeyword)
		{
			if (findKeyword(line, i, "BEGIN_EVENT_TABLE")
			        || findKeyword(line, i, "BEGIN_DISPATCH_MAP")
			        || findKeyword(line, i, "BEGIN_EVENT_MAP")
			        || findKeyword(line, i, "BEGIN_MESSAGE_MAP")
			        || findKeyword(line, i, "BEGIN_PROPPAGEIDS"))
			{
				nextLineIsEventIndent = true;
				break;
			}
			if (findKeyword(line, i, "END_EVENT_TABLE")
			        || findKeyword(line, i, "END_DISPATCH_MAP")
			        || findKeyword(line, i, "END_EVENT_MAP")
			        || findKeyword(line, i, "END_MESSAGE_MAP")
			        || findKeyword(line, i, "END_PROPPAGEIDS"))
			{
				isInEventTable = false;
				break;
			}
		}

		// ----------------  process SQL  -----------------------------------------------

		if (isInSQL)
		{
			if (isBeginDeclareSectionSQL(line, i))
				nextLineIsDeclareIndent = true;
			if (isEndDeclareSectionSQL(line, i))
				isInDeclareSection = false;
			break;
		}

		// ----------------  process switch statements  ---------------------------------

		if (isPotentialKeyword && findKeyword(line, i, "switch"))
		{
			switchDepth++;
			switchStack.push_back(sw);                      // save current variables
			sw.switchBracketCount = 0;
			sw.unindentCase = false;                        // don't clear case until end of switch
			i += 5;                                         // bypass switch statement
			continue;
		}

		// just want unindented switch statements from this point

		if (caseIndent
		        || switchDepth == 0
		        || (isInPreprocessor && !preprocessorIndent))
		{
			// bypass the entire word
			if (isPotentialKeyword)
			{
				string name = getCurrentWord(line, i);
				i += name.length() - 1;
			}
			continue;
		}

		i = processSwitchBlock(line, i);

	}   // end of for loop * end of for loop * end of for loop * end of for loop

	if (isInEventTable || isInDeclareSection)
	{
		if (line.length() == 0 || line[0] != '#')
			indentLine(line, 1);
	}

	if (shouldIndentLine && sw.unindentDepth > 0)
		unindentLine(line, sw.unindentDepth);
}
Ejemplo n.º 17
0
/**
 * additional formatting for line of source code.
 * every line of source code in a source code file should be sent
 *     one after the other to this function.
 * indents event tables
 * unindents the case blocks
 *
 * @param line       the original formatted line will be updated if necessary.
 */
void ASEnhancer::enhance(string &line)
{
	bool   isSpecialChar = false;
	size_t  lineLength;                             // length of the line being parsed

	lineNumber++;
	lineLength = line.length();

	// check for beginning of event table
	if (nextLineIsEventTable)
	{
		isInEventTable = true;
		nextLineIsEventTable = false;
	}

	if (lineLength == 0
	        && ! isInEventTable
	        && ! emptyLineFillX)
		return;

	// test for unindent on attached brackets
	if (unindentNextLine)
	{
		sw.unindentDepth++;
		sw.unindentCase = true;
		unindentNextLine = false;
		TRcase(" unindent case ", sw.unindentDepth);
	}

	// parse characters in the current line.

	for (size_t i = 0; i < lineLength; i++)
	{
		char ch = line[i];

		// bypass whitespace
		if (isWhiteSpaceX(ch))
			continue;

		// handle special characters (i.e. backslash+character such as \n, \t, ...)
		if (isSpecialChar)
		{
			isSpecialChar = false;
			continue;
		}
		if (!(isInComment) && line.compare(i, 2, "\\\\") == 0)
		{
			i++;
			continue;
		}
		if (!(isInComment) && ch == '\\')
		{
			isSpecialChar = true;
			continue;
		}

		// handle quotes (such as 'x' and "Hello Dolly")
		if (!(isInComment) && (ch == '"' || ch == '\''))
		{
			if (!isInQuote)
			{
				quoteChar = ch;
				isInQuote = true;
			}
			else if (quoteChar == ch)
			{
				isInQuote = false;
				continue;
			}
		}

		if (isInQuote)
			continue;

		// handle comments

		if (!(isInComment) && line.compare(i, 2, "//") == 0)
		{
			// check for windows line markers
			if (line.compare(i + 2, 1, "\xf0") > 0)
				lineNumber--;
			break;                 // finished with the line
		}
		else if (!(isInComment) && line.compare(i, 2, "/*") == 0)
		{
			isInComment = true;
			i++;
			continue;
		}
		else if ((isInComment) && line.compare(i, 2, "*/") == 0)
		{
			isInComment = false;
			i++;
			continue;
		}

		if (isInComment)
			continue;

		// if we have reached this far then we are NOT in a comment or string of special characters

		if (line[i] == '{')                                 // if open bracket
			bracketCount++;

		if (line[i] == '}')                     // if close bracket
			bracketCount--;

		// ----------------  process event tables  --------------------------------------

		// check for event table begin
		if (findKeyword(line, i, "BEGIN_EVENT_TABLE")
		        || findKeyword(line, i, "BEGIN_MESSAGE_MAP"))
			nextLineIsEventTable = true;

		// check for event table end
		if (findKeyword(line, i, "END_EVENT_TABLE")
		        || findKeyword(line, i, "END_MESSAGE_MAP"))
			isInEventTable = false;

		// ----------------  process switch statements  ---------------------------------

		if (findKeyword(line, i, "switch"))                 // if switch statement
		{
			switchDepth++;                                  // bump switch depth
			TRswitch(" switch ", switchDepth);
			swVector.push_back(sw);                         // save current variables
			sw.switchBracketCount = 0;
			sw.unindentCase = false;                        // don't clear case until end of switch
			i += 5;                                         // bypass switch statement
			continue;
		}

		// just want switch statements from this point

		if (caseIndentX || switchDepth == 0)               // from here just want switch statements
			continue;                                      // get next char

		if (line[i] == '{')                                 // if open bracket
		{
			sw.switchBracketCount++;
			if (lookingForCaseBracket)                      // if 1st after case statement
			{
				sw.unindentCase = true;                     // unindenting this case
				sw.unindentDepth++;                         // bump depth
				lookingForCaseBracket = false;              // not looking now
				TRcase(" unindent case ", sw.unindentDepth);
			}
			continue;
		}

		lookingForCaseBracket = false;                      // no opening bracket, don't indent

		if (line[i] == '}')                                 // if close bracket
		{
			sw.switchBracketCount--;
			if (sw.switchBracketCount == 0)                 // if end of switch statement
			{
				TRswitch("  endsw ", switchDepth);
				switchDepth--;                              // one less switch
				sw = swVector.back();                       // restore sw struct
				swVector.pop_back();                        // remove last entry from stack
			}
			continue;
		}

		// look for case or default header

		if (findKeyword(line, i, "case") || findKeyword(line, i, "default"))
		{
			if (sw.unindentCase)                            // if unindented last case
			{
				sw.unindentCase = false;                    // stop unindenting previous case
				sw.unindentDepth--;                         // reduce depth
			}
			bool isInQuote = false;
			char quoteChar = ' ';
			for (; i < lineLength; i++)                     // find colon
			{
				if (isInQuote)
				{
					if (line[i] == '\\')
					{
						i++;								// bypass next char
						continue;
					}
					else if (line[i] == quoteChar)			// check ending quote
					{
						isInQuote = false;
						quoteChar = ' ';
						continue;
					}
					else
					{
						continue;							// must close quote before continuing
					}
				}
				if (line[i] == '\'' || line[i] == '\"')	// check opening quote
				{
					isInQuote = true;
					quoteChar = line[i];
					continue;
				}
				if (line[i] == ':')
				{
					if ((i + 1 < lineLength) && (line[i + 1] == ':'))
						i++;								// bypass scope resolution operator
					else
						break;								// found it
				}
			}
			i++;
			for (; i < lineLength; i++)                     // bypass whitespace
			{
				if (!(isWhiteSpaceX(line[i])))
					break;
			}
			if (i < lineLength)                             // check for bracket
			{
				if (line[i] == '{')                         // if bracket found
				{
					sw.switchBracketCount++;
					unindentNextLine = true;                // start unindenting on next line
					continue;
				}
			}
			lookingForCaseBracket = true;                   // bracket must be on next line
			i--;                                            // need to check for comments
			continue;
		}
	}   // end of for loop

	if (isInEventTable) 									// if need to indent
		indentLine(line, 1);               					//    do it

	if (sw.unindentDepth > 0)                               // if need to unindent
		unindentLine(line, sw.unindentDepth);               //    do it
}
Ejemplo n.º 18
0
/**
 * process the character at the current index in a switch block.
 *
 * @param line          a reference to the line to indent.
 * @param index         the current line index.
 * @return              the new line index.
 */
size_t ASEnhancer::processSwitchBlock(string  &line, size_t index)
{
	size_t i = index;
	bool isPotentialKeyword = isCharPotentialHeader(line, i);

	if (line[i] == '{')
	{
		sw.switchBracketCount++;
		if (lookingForCaseBracket)                      // if 1st after case statement
		{
			sw.unindentCase = true;                     // unindenting this case
			sw.unindentDepth++;
			lookingForCaseBracket = false;              // not looking now
		}
		return i;
	}
	lookingForCaseBracket = false;                      // no opening bracket, don't indent

	if (line[i] == '}')                                 // if close bracket
	{
		sw.switchBracketCount--;
		if (sw.switchBracketCount == 0)                 // if end of switch statement
		{
			switchDepth--;                              // one less switch
			sw = swVector.back();                       // restore sw struct
			swVector.pop_back();                        // remove last entry from stack
		}
		return i;
	}

	if (isPotentialKeyword
	        && (findKeyword(line, i, "case") || findKeyword(line, i, "default")))
	{
		if (sw.unindentCase)                            // if unindented last case
		{
			sw.unindentCase = false;                    // stop unindenting previous case
			sw.unindentDepth--;                         // reduce depth
		}

		i = findCaseColon(line, i);

		i++;
		for (; i < line.length(); i++)                  // bypass whitespace
		{
			if (!isWhiteSpace(line[i]))
				break;
		}
		if (i < line.length())
		{
			if (line[i] == '{')
			{
				sw.switchBracketCount++;
				unindentNextLine = true;
				return i;
			}
		}
		lookingForCaseBracket = true;                   // bracket must be on next line
		i--;                                            // need to check for comments
		return i;
	}
	if (isPotentialKeyword)
	{
		string name = getCurrentWord(line, i);          // bypass the entire name
		i += name.length() - 1;
	}
	return i;
}
Ejemplo n.º 19
0
/**
 * Reads the segments[] array (see applyPattern()) and parses the
 * segments[1..3] into a Format* object.  Stores the format object in
 * the subformats[] array.  Updates the argTypes[] array type
 * information for the corresponding argument.
 *
 * @param formatNumber index into subformats[] for this format
 * @param segments array of strings with the parsed pattern segments
 * @param parseError parse error data (output param)
 * @param ec error code
 */
void
MessageFormat::makeFormat(int32_t formatNumber, 
                          UnicodeString* segments,
                          UParseError& parseError,
                          UErrorCode& ec) {
    if (U_FAILURE(ec)) {
        return;
    }

    // Parse the argument number
    int32_t argumentNumber = stou(segments[1]); // always unlocalized!
    if (argumentNumber < 0) {
        ec = U_INVALID_FORMAT_ERROR;
        return;
    }

    // Parse the format, recording the argument type and creating a
    // new Format object (except for string arguments).
    Formattable::Type argType;
    Format *fmt = NULL;
    int32_t typeID, styleID;
    DateFormat::EStyle style;

    switch (typeID = findKeyword(segments[2], TYPE_IDS)) {

    case 0: // string
        argType = Formattable::kString;
        break;

    case 1: // number
        argType = Formattable::kDouble;

        switch (findKeyword(segments[3], NUMBER_STYLE_IDS)) {
        case 0: // default
            fmt = NumberFormat::createInstance(fLocale, ec);
            break;
        case 1: // currency
            fmt = NumberFormat::createCurrencyInstance(fLocale, ec);
            break;
        case 2: // percent
            fmt = NumberFormat::createPercentInstance(fLocale, ec);
            break;
        case 3: // integer
            argType = Formattable::kLong;
            fmt = createIntegerFormat(fLocale, ec);
            break;
        default: // pattern
            fmt = NumberFormat::createInstance(fLocale, ec);
            if (fmt &&
                fmt->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
                ((DecimalFormat*)fmt)->applyPattern(segments[3],parseError,ec);
            }
            break;
        }
        break;

    case 2: // date
    case 3: // time
        argType = Formattable::kDate;
        styleID = findKeyword(segments[3], DATE_STYLE_IDS);
        style = (styleID >= 0) ? DATE_STYLES[styleID] : DateFormat::kDefault;

        if (typeID == 2) {
            fmt = DateFormat::createDateInstance(style, fLocale);
        } else {
            fmt = DateFormat::createTimeInstance(style, fLocale);
        }

        if (styleID < 0 &&
            fmt != NULL &&
            fmt->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
            ((SimpleDateFormat*)fmt)->applyPattern(segments[3]);
        }
        break;

    case 4: // choice
        argType = Formattable::kDouble;

        fmt = new ChoiceFormat(segments[3], parseError, ec);
        break;

    case 5: // spellout
        argType = Formattable::kDouble;
        fmt = makeRBNF(URBNF_SPELLOUT, fLocale, segments[3], ec);
        break;
    case 6: // ordinal
        argType = Formattable::kDouble;
        fmt = makeRBNF(URBNF_ORDINAL, fLocale, segments[3], ec);
        break;
    case 7: // duration
        argType = Formattable::kDouble;
        fmt = makeRBNF(URBNF_DURATION, fLocale, segments[3], ec);
        break;
    default:
        argType = Formattable::kString;
        ec = U_ILLEGAL_ARGUMENT_ERROR;
        break;
    }

    if (fmt==NULL && argType!=Formattable::kString && U_SUCCESS(ec)) {
        ec = U_MEMORY_ALLOCATION_ERROR;
    }
    
    if (!allocateSubformats(formatNumber+1) ||
        !allocateArgTypes(argumentNumber+1)) {
        ec = U_MEMORY_ALLOCATION_ERROR;
    }

    if (U_FAILURE(ec)) {
        delete fmt;
        return;
    }

    // Parse succeeded; record results in our arrays
    subformats[formatNumber].format = fmt;
    subformats[formatNumber].offset = segments[0].length();
    subformats[formatNumber].arg = argumentNumber;
    subformatCount = formatNumber+1;

    // Careful here: argumentNumber may in general arrive out of
    // sequence, e.g., "There was {2} on {0,date} (see {1,number})."
    argTypes[argumentNumber] = argType;
    if (argumentNumber+1 > argTypeCount) {
        argTypeCount = argumentNumber+1;
    }
}