예제 #1
0
파일: VdfParser.cpp 프로젝트: LiDongbao/YAP
bool VdfParser::ProcessArrayDeclaration(Tokens& tokens, VariableSpace& variables)
{
    static map<TokenType, int> token_to_array_property{
        {TokenKeywordFloat, VariableFloatArray},
        {TokenKeywordInt, VariableIntArray},
        {TokenKeywordString, VariableStringArray},
        {TokenKeywordBool, VariableBoolArray},
		{TokenId, VariableStructArray},
    };

	tokens.AssertToken(TokenKeywordArray, true);
	tokens.AssertToken(TokenLessThan, true);

	auto type = tokens.GetCurrentToken().type;
	auto element_type_id = tokens.GetCurrentToken().text;
	auto fq_type_id = ResolveFqId(element_type_id.c_str(), true, tokens);

	assert(type == TokenKeywordFloat || type == TokenKeywordInt ||
		   type == TokenKeywordBool || type == TokenKeywordString ||
			type == TokenId);
	tokens.Next();
	tokens.AssertToken(TokenGreaterThan, true);

	auto id = (&variables == _variables.get()) ?
		GetFqId(tokens.GetId().c_str()) : tokens.GetId();

	if (!tokens.IsTokenOfType(TokenSharp, true))
	{
		variables.AddArray(fq_type_id.c_str(), id.c_str(), L"");
	}
	else
	{
		tokens.AssertToken(TokenLessThan, true);
		auto start_index = _wtoi(tokens.GetLiteralValue().c_str());
		tokens.AssertToken(TokenComma, true);
		auto end_index = _wtoi(tokens.GetLiteralValue().c_str());
		tokens.AssertToken(TokenGreaterThan, true);

		for (int i = start_index; i <= end_index; ++i)
		{
			wostringstream output;
			output << id << i;
			auto variable_id = (&variables == _variables.get()) ?
				GetFqId(output.str().c_str()) : output.str();
			variables.AddArray(fq_type_id.c_str(), variable_id.c_str(), L"");
		}
	}
	tokens.AssertToken(TokenSemiColon, true);

	return true;
}
예제 #2
0
파일: VdfParser.cpp 프로젝트: LiDongbao/YAP
bool VdfParser::ProcessSimpleDeclaration(Tokens& tokens)
{
    assert(_variables);

	auto type = tokens.GetCurrentToken().type;
    auto type_id = tokens.GetCurrentToken().text;

	assert(type == TokenKeywordFloat || type == TokenKeywordInt ||
           type == TokenKeywordBool || type == TokenKeywordString ||
           type == TokenId);

	tokens.Next();
	auto id = tokens.GetId();
	auto fq_type_id = ResolveFqId(type_id.c_str(), true, tokens);

	if (!tokens.IsTokenOfType(TokenSharp, true))
	{
        _variables->Add(fq_type_id.c_str(), GetFqId(id.c_str()).c_str(), L"");
	}
	else
	{
		tokens.AssertToken(TokenLessThan, true);

		auto start_index = boost::lexical_cast<int>(tokens.GetLiteralValue());
		tokens.AssertToken(TokenComma, true);
		auto end_index = boost::lexical_cast<int>(tokens.GetLiteralValue());
		tokens.AssertToken(TokenGreaterThan, true);

		for (int i = start_index; i <= end_index; ++i)
		{
			wostringstream output;
			output << id << i;
			wstring variable_id = GetFqId(output.str().c_str());
			
            _variables->Add(fq_type_id.c_str(), variable_id.c_str(), L"");
		}
	}
	tokens.AssertToken(TokenSemiColon, true);

	return true;
}
예제 #3
0
// ----------------------------------------------------------------------------
// String.h
bool Test_String()
{
    TTRACE(_T("====================================================="));
    // StrRCSpn テスト。
    {
        const TCHAR* strCharSet = _T("abc");
        int ret;

        const TCHAR* str1 = _T("nakayama");
        ret = StrRCSpn(str1, strCharSet);
        if (ret != 7)
        {
            TTRACE(_T("StrRCSpn# failed! ret=%d"), ret);
            return false;
        }

        const TCHAR* str2 = _T("erio");
        ret = StrRCSpn(str2, strCharSet);
        if (ret != -1)
        {
            TTRACE(_T("StrRCSpn# failed! ret=%d"), ret);
            return false;
        }

        const TCHAR* str3 = _T("nakayama erio");
        ret = StrRCSpn(str3, strCharSet);
        if (ret != 7)
        {
            TTRACE(_T("StrRCSpn# failed! ret=%d"), ret);
            return false;
        }
    }

    // StrRStr テスト。
    {
        const TCHAR* result = NULL;

        const TCHAR* str1 = _T("Romancing SaGa, SaGa Frontier, Unlimited SaGa");
        result = StrRStr(str1, _T("SaGa"));
        if (result == NULL || _tcscmp(_T("SaGa"), result) != 0)
        {
            TTRACE(_T("StrRStr# failed! result=%s"), result);
            return false;
        }

        const TCHAR* str2 = _T("Romancing SaGa, SaGa Frontier, Unlimited SaGa, Romancing SaGa -Minstrel Song-");
        result = StrRStr(str2, _T("SaGa"));
        if (result == NULL || _tcscmp(_T("SaGa -Minstrel Song-"), result) != 0)
        {
            TTRACE(_T("StrRStr# failed! result=%s"), result);
            return false;
        }

        result = StrRStr(str2, _T("Itoken"));
        if (result != NULL)
        {
            TTRACE(_T("StrRStr# failed! result=%s"), result);
            return false;
        }
    }

    // Tokens テスト。
    {
        Tokens<TCHAR> tokens;
        tokens.Set(_T("I love \"Romancing SaGa\" (Super Famicom software)"), _T(" "), _T("\"\"()"));
        TString token;
        if (!tokens.Next(token) || token.compare(_T("I")) != 0)
        {
            TTRACE(_T("Tokens# failed! result=%s"), token.c_str());
            return false;
        }

        if (!tokens.Next(token) || token.compare(_T("love")) != 0)
        {
            TTRACE(_T("Tokens# failed! result=%s"), token.c_str());
            return false;
        }

        if (!tokens.Next(token) || token.compare(_T("Romancing SaGa")) != 0)
        {
            TTRACE(_T("Tokens# failed! result=%s"), token.c_str());
            return false;
        }

        if (!tokens.Next(token) || token.compare(_T("Super Famicom software")) != 0)
        {
            TTRACE(_T("Tokens# failed! result=%s"), token.c_str());
            return false;
        }

        if (tokens.Next(token))
        {
            TTRACE(_T("Tokens# failed!"));
            return false;
        }

        if (tokens.Next(token))
        {
            TTRACE(_T("Tokens# failed!"));
            return false;
        }
    }

    return true;
}
예제 #4
0
파일: VdfParser.cpp 프로젝트: LiDongbao/YAP
bool VdfParser::ProcessStructDeclaration(Tokens& tokens)
{
    tokens.AssertToken(TokenKeywordStruct, true);
    auto struct_id = GetFqId(tokens.GetId().c_str());

    tokens.AssertToken(TokenLeftBrace, true);

    VariableSpace struct_variables;
	static std::set<TokenType> s_allowed_types = {
		TokenKeywordBool, TokenKeywordFloat, TokenKeywordInt, TokenKeywordString,
		TokenKeywordArray, TokenId };
    do
    {
        auto& type_token = tokens.GetCurrentToken();
        if (s_allowed_types.find(type_token.type) == s_allowed_types.end())
        {
            throw(CompileError(type_token, CompileErrorTypeExpected,
                               L"Expected either one of float, int, string, bool, array, or a struct name."));
        }

		if (type_token.type == TokenKeywordArray)
		{
			ProcessArrayDeclaration(tokens, struct_variables);
		}
		else
		{
			auto type_id = ResolveFqId(type_token.text.c_str(), true, tokens);
			if (type_token.type == TokenId)
			{
				if (!_variables->TypeExists(type_id.c_str()))
					throw CompileError(type_token, CompileErrorTypeNotFound, L"Type not found.");

				if (type_token.text == struct_id)
					throw CompileError(type_token, CompileErrorNestStruct, L"Nested struct definition not allowed.");

			}

			tokens.Next();
			auto& member_token = tokens.GetCurrentToken();

			if (struct_variables.VariableExists(member_token.text.c_str()))
				throw CompileError(type_token, CompileErrorMemeberExists, L"Duplicated struct member ids.");


			auto prototype = _variables->GetType(type_id.c_str());
			if (prototype == nullptr)
				throw CompileError(type_token, CompileErrorTypeNotFound, L"Type not found.");

			auto member = dynamic_cast<IVariable*>(prototype->Clone());
			assert(member != nullptr);
			member->SetId(member_token.text.c_str());
			struct_variables.Add(member);

			tokens.Next();
			tokens.AssertToken(TokenSemiColon, true);
		}
    } while (!tokens.IsTokenOfType(TokenRightBrace, false));

	tokens.Next();
	tokens.AssertToken(TokenSemiColon, true);

    _variables->AddType(struct_id.c_str(), struct_variables.Variables());

    return true;
}