예제 #1
0
bool CScanner::NextToken()
{
	SkipWhiteSpace();
	if (ErrorString != "")
		return false;
// 	if (Pos >= SourceLength)
// 		return false;
	_off_t OldPos = Pos;
	char c = cget();
	if (isdigit(c) || // Thinks a little, while reading this condition, it might be a bit unreadable.
			(
				(
					c == '.' && 
					(
						(IncPos(), isdigit(cget())) || (DecPos(), false)				
					)
				) &&
				(DecPos(), true)
			)
		)
		return ParseNumber() && OldPos != Pos;
	else if (isalpha(c) || c == '_')
		return ParseIdentifier() && OldPos != Pos;
	else if (MatchPrefix("'"))
		return ParseCharacterLiteral() && OldPos != Pos;
	else if (MatchPrefix("\""))
		return ParseStringLiteral() && OldPos != Pos;
	else if (SymbolicTokenMapping.find(string() += c))
		return ParseSymbol() && OldPos != Pos;
	else if (c == 0)
		return true;
	else
		ErrorString = "Unrecognized character at line: ";// + itoa(CurrentLine) + ", Column: " + itoa(CurrentColumn);
	return false;
}
예제 #2
0
bool CScanner::ParseNumber()
{
	UpdateCurrentToken();
	string TempString = "";
	while (isalnum(cget()) || cget() == '.' || cget() == '+' || cget() == '-')
		TempString += cget(), IncPos();
	string ClearString = "uUlL";
	if	(
			TempString[1] != 'x' && TempString[1] != 'X'
// 			TempString.find('e') != string::npos ||
// 			TempString.find('E') != string::npos || 
// 			TempString.find('.') != string::npos ||
			
		)
		ClearString += "fF";
	while (ClearString.find(TempString[TempString.length() - 1]) != string::npos)
		TempString.erase(TempString.length()- 1);
	
	CurrentToken.Kind = DTM_TOKEN::LITERAL::NUMBER::INTEGER;
	if (TempString[1] == 'x' || TempString[1] == 'X')
		try
		{
			CurrentToken.Value = FromHexadecimalString(TempString);
			return true;
		}
		catch (...)
		{
			ErrorString = "Bad hexadecimal integral literal.";
			return false;
		}

	try
	{
		CurrentToken.Value = lexical_cast<int>(TempString);
		return true;
	}
	catch (...)
	{
	}

	try
	{
		CurrentToken.Value = lexical_cast<float>(TempString);
		CurrentToken.Kind = DTM_TOKEN::LITERAL::NUMBER::FLOAT;
		return true;
	}
	catch (...)
	{
		ErrorString = "Bad number literal.";
	}

	return true;
}
예제 #3
0
bool CScanner::ParseIdentifier()
{
	UpdateCurrentToken();
	string TempString = "";
	while (isalnum(cget()) || cget() == '_')
		TempString += cget(), IncPos();
	if (isKeyword(TempString))
		CurrentToken.Kind = GetKeywordKind(TempString);
	else
		CurrentToken.Kind = DTM_TOKEN::IDENTIFIER;
	CurrentToken.Value = TempString;
	return true;
}
예제 #4
0
bool CScanner::MatchPrefix(const string &Prefix, unsigned int Offset /*= 0*/)
{
	if (Offset >= Prefix.length())
		return true;
	bool Result = false;
	if (Source[Pos] == Prefix[Offset])
	{
		IncPos();
		Result = MatchPrefix(Prefix, Offset + 1);
		if (!Result)
			DecPos();
	}
	return Result;
}
예제 #5
0
bool CScanner::ParseSymbol()
{
	string TempString = "";
	UpdateCurrentToken();	
	while (isSymbol(cget()) && TempString.length() < 3)
		TempString += cget(), IncPos();
	while(!SymbolicTokenMapping.find(TempString))
	{
		TempString.erase(TempString.end() - 1), DecPos();
	}
	CurrentToken.Kind = SymbolicTokenMapping[TempString];
	CurrentToken.Value.reset();
	CurrentToken.Value = TempString;
	return true;
}
예제 #6
0
bool CScanner::ParseStringLiteral()
{
	UpdateCurrentToken();
	string TempString = "";
	while (cget() != '"' && cget() != 0)
	{
		if (isNewline())
		{
			ErrorString = "Newline in string literal.";
			return false;
		}
		if (cget() == '\\')
		{
			IncPos();
			if (cget() == 'x')
			{
				IncPos();
				string VeryTempString = "x";
				while(isxdigit(cget()))
					VeryTempString += cget(), IncPos();
				try
				{
					TempString += EscapeSequenceToValue(VeryTempString);
					continue;
				}
				catch (positive_overflow &e)
				{
					ErrorString = "Hexadecimal constant is invalid (may be too large for character).";
					return false;
				}
			}
			else
			{
				TempString += EscapeSequenceToValue(string() += cget());
				IncPos();
				continue;
			}
		}
		TempString += cget();
		IncPos();
	}
	IncPos();
	CurrentToken.Kind = DTM_TOKEN::LITERAL::STRING;
	CurrentToken.Value = TempString;
	return true;
}
예제 #7
0
bool CScanner::ParseCharacterLiteral()
{
	enum
	{
		BEGIN,
		ESCAPE_SEQUENCE_FOUND,
		HEXADECIMAL_ESCAPE_SEQUENCE_FOUND,
		BEGIN_FINISHING,
		FINISHED,
	};
	enum
	{				// We discovered that between the ' ' is:
		R_SIMPLE,	//	just a c-character
		R_ESCHEX,	//	hexadecimal escape sequence
		R_ESCSEQ,	//	simple escape sequence
		R_NOTHIN,	//	<- Initial state.
	};
	int State = BEGIN;
	int ResultKind = R_NOTHIN;
	UpdateCurrentToken();
	CurrentToken.Kind = DTM_TOKEN::LITERAL::NUMBER::INTEGER;
	string TempString = "";
	bool ErrFlag = cget() == 0;
	while (State != FINISHED && !ErrFlag)
	{
		switch(State)
		{
		case BEGIN:
			ErrFlag = cget() == '\'';
			TempString = cget();
			if (cget() == '\\')
				State = ESCAPE_SEQUENCE_FOUND;
			else
				State = BEGIN_FINISHING, ResultKind = R_SIMPLE;
			break;
		case ESCAPE_SEQUENCE_FOUND:
			ErrFlag = cget() == '\'';
			TempString = cget();
			if (cget() == 'x')
				State = HEXADECIMAL_ESCAPE_SEQUENCE_FOUND, ResultKind = R_ESCHEX;
			else 
				State = BEGIN_FINISHING, ResultKind = R_ESCSEQ;
			break;
		case HEXADECIMAL_ESCAPE_SEQUENCE_FOUND:
			ErrFlag = cget() == '\'';
			while (isxdigit(cget()))
				TempString += cget(), IncPos();
			State = BEGIN_FINISHING, DecPos();
			break;
		case BEGIN_FINISHING:
			ErrFlag = cget() != '\'';
			State = FINISHED;
			break;
		}
		IncPos();
	}
	if (ErrFlag)
	{
		ErrorString = "Invalid character constant.";
		return false;
	}
	switch (ResultKind)
	{
	case R_SIMPLE:
		CurrentToken.Value = TempString[0];
		break;
	case R_ESCHEX: case R_ESCSEQ:
		try
		{
			CurrentToken.Value = EscapeSequenceToValue(TempString);
		}
		catch (...)	// positive_overflow ?
		{
			ErrFlag = true;
		}		
		break;
	case R_NOTHIN:
		break;
	}
	if (ErrFlag)
		ErrorString = "Hexadecimal constant is invalid (may be too large for character).";
	return !ErrFlag;
}
예제 #8
0
bool CScanner::SkipWhiteSpace()
{
	enum EScannerState
	{
		SEARCH_FOR_WHITE_SPACE,
		NEXT_TOKEN,
		BEGIN_COMMENT,
		C_COMMENT_BODY,
		CPP_COMMENT_BODY,
		CPP_COMMENT_GOING_NEWLINE,
		PREPARE_TO_EXIT_C_COMMENT_BLOCK,
		PREPARE_TO_EXIT_CPP_COMMENT_BLOCK,
		BEGIN_PP,
		PP_GOING_NEW_LINE,	
		BEGIN_SYMBOL,
		BEGIN_IDENTIFIER,
		BEGIN_NUMBER,
		END_SCAN,
	};
	char c;
	EScannerState State = SEARCH_FOR_WHITE_SPACE;
	while (cget() != 0)
	{
		c = cget();
		if (c == '\n')
			IncLineCounter();
		switch (State)
		{
		case SEARCH_FOR_WHITE_SPACE:
			switch(c)
			{
			case '\t': case'\n': case '\v': case '\r': case ' ': case '\f':
				break;
			case '/':
				State = BEGIN_COMMENT;
				break;
			case '#':
				State = BEGIN_PP;
				break;
			default:
				return true;
			}
			break;
		case BEGIN_COMMENT:
			if (c == '*')
				State = C_COMMENT_BODY;
			else if (c == '/')
				State = CPP_COMMENT_BODY;
			else
			{
				State = BEGIN_SYMBOL;
				Pos--;
				return true;
			}
			break;
		case C_COMMENT_BODY:
			if (c != '*')
				break;
			else
				State = PREPARE_TO_EXIT_C_COMMENT_BLOCK;
			break;
		case PREPARE_TO_EXIT_C_COMMENT_BLOCK:
			switch (c)
			{
			case '*':
				break;
			case '/':
				State = SEARCH_FOR_WHITE_SPACE;				
				break;
			default:
				State = C_COMMENT_BODY;
				break;
			}
			break;
		case CPP_COMMENT_BODY:
			if (c == '\\')
				State = CPP_COMMENT_GOING_NEWLINE;
			else if (c != '\r' && c != '\n')
				break;
			else if (c == '\n')
				State = SEARCH_FOR_WHITE_SPACE;
			break;
		case CPP_COMMENT_GOING_NEWLINE:
			if (c == '\r' || c == '\\')
				break;
			State = CPP_COMMENT_BODY;
			break;
		case BEGIN_PP:
			switch(c)
			{
			case '\\':
				State = PP_GOING_NEW_LINE;
				break;
			case '\n':
				State = SEARCH_FOR_WHITE_SPACE;
				break;
			default:
				break;
			}
			break;
		case PP_GOING_NEW_LINE:
			if (c == '\r' || c == '\\')
				break;
			State = BEGIN_PP;
			break;
		default:
			assert(false);
			break;
		}
		IncPos();
	}
	if (State == C_COMMENT_BODY || State == PREPARE_TO_EXIT_C_COMMENT_BLOCK)
	{
		ErrorString = "Unclosed multi-line comment.";
		return false;
	}
	return true;
}
예제 #9
0
파일: UILine.cpp 프로젝트: OLR-xray/OLR-3.0
const CUILine* CUILine::CutByLength(CGameFont* pFont, float length, BOOL cut_word)
{
	R_ASSERT(GetSize() > 0);
	// if first sub line is void then delete it

	Position pos;
	InitPos(pos);

	if (!pos.word_1.exist()) // void string
	{
		if (m_subLines[0].m_last_in_line)
		{
			m_subLines.erase(m_subLines.begin());
			return GetEmptyLine();
		}
		else
		{
			m_subLines.erase(m_subLines.begin());
			InitPos(pos);
		}
	}


	float len2w1 = GetLength_inclusiveWord_1(pos, pFont);
//.	* scale; bacause of our fonts not scaled

    if (!pos.word_2.exist())
	{
		if (cut_word && len2w1 > length)
			return CutWord(pFont, length);		
		else
			return Cut2Pos(pos);
	}

	
	float len2w2 = GetLength_inclusiveWord_2(pos, pFont);

	if (len2w1 > length)
	{
		if (cut_word)
            return CutWord(pFont, length);		
		else
            return Cut2Pos(pos);
	}
	else if (len2w1 <= length && len2w2 > length)
	{
		// cut whole first word
		return Cut2Pos(pos);  // all right :)
	}
	else // if (len2w1 > length && len2w2 > length)
	{
		while (IncPos(pos))
		{
			len2w1 = GetLength_inclusiveWord_1(pos, pFont);
			if(!pos.word_2.exist())
			{
				return Cut2Pos(pos);
			}
			len2w2 = GetLength_inclusiveWord_2(pos, pFont);
			if (len2w1 <= length && len2w2 > length)
				return Cut2Pos(pos);
		}
     
		return Cut2Pos(pos, false);
	}

}