Esempio n. 1
0
// ParseVariableDeclaration
//------------------------------------------------------------------------------
bool BFFParser::ParseVariableDeclaration( BFFIterator & iter, const AString & varName, BFFStackFrame * frame )
{
	m_SeenAVariable = true;

	// look for an appropriate operator
	BFFIterator operatorIter( iter );
	bool modification = false;
	if ( *iter == BFF_VARIABLE_ASSIGNMENT )
	{
		// assignment
	}
	else if ( ( *iter == BFF_VARIABLE_CONCATENATION ) ||
			  ( *iter == BFF_VARIABLE_SUBTRACTION ) )
	{
		// concatenation
		modification = true;
	}
	else
	{
		Error::Error_1016_UnexepectedCharFollowingVariableName( iter );
		return false;
	}

	// skip the assignment symbol and whitespace
	iter++;
	iter.SkipWhiteSpaceAndComments();
	if ( iter.IsAtEnd() )
	{
		Error::Error_1012_UnexpectedEndOfFile( iter );
		return false;
	}

	char openToken = *iter;
	char closeToken = 0;
	bool ok = false;
	if ( ( openToken == '"' ) || ( openToken == '\'' ) )
	{
		closeToken = openToken;
		ok = true;
	}
	else if ( openToken == BFF_SCOPE_OPEN )
	{
		closeToken = BFF_SCOPE_CLOSE;
		ok = true;
	}
	else if ( openToken == BFF_STRUCT_OPEN )
	{
		closeToken = BFF_STRUCT_CLOSE;
		ok = true;
	}
	else if ( ( openToken >= '0' ) && ( openToken <= '9' ) )
	{
		if ( modification )
		{
			Error::Error_1027_CannotModify( operatorIter, varName, BFFVariable::VAR_ANY, BFFVariable::VAR_INT );
			return false;
		}

		// integer value?
		BFFIterator startIntValue( iter );
		while ( iter.IsAtEnd() == false )
		{
			iter++;
			if ( ( *iter < '0' ) || ( *iter > '9' ) )
			{
				break; // end of integer
			}
		}
		if ( startIntValue.GetDistTo( iter ) > 10 )
		{
			Error::Error_1018_IntegerValueCouldNotBeParsed( startIntValue );
			return false;
		}
		AStackString<> intAsString( startIntValue.GetCurrent(), iter.GetCurrent() );
		int i = 0;
		if ( sscanf( intAsString.Get(), "%i", &i ) != 1 )
		{
			Error::Error_1018_IntegerValueCouldNotBeParsed( startIntValue );
			return false;
		}
		return StoreVariableInt( varName, i, frame );
	}
	else if ( ( *iter == 't' ) || ( *iter == 'f' ) )
	{
		// might be 'true' or 'false'
		BFFIterator startBoolValue( iter );
		if ( iter.ParseToNext( 'e' ) == true )
		{
			iter++;
			if ( ( startBoolValue.GetDistTo( iter ) <= 5 ) )
			{
				AStackString<8> value( startBoolValue.GetCurrent(), iter.GetCurrent() );
				if ( value == "true" )
				{
					if ( modification )
					{
						Error::Error_1027_CannotModify( operatorIter, varName, BFFVariable::VAR_ANY, BFFVariable::VAR_BOOL );
						return false;
					}
					return StoreVariableBool( varName, true, frame );
				}
				else if ( value == "false" )
				{
					if ( modification )
					{
						Error::Error_1027_CannotModify( operatorIter, varName, BFFVariable::VAR_ANY, BFFVariable::VAR_BOOL );
						return false;
					}
					return StoreVariableBool( varName, false, frame );
				}
			}
		}

		// not a valid bool value
	}
	else if ( *iter == BFF_DECLARE_VAR_INTERNAL ||
			  *iter == BFF_DECLARE_VAR_PARENT )
	{
		return StoreVariableToVariable( varName, iter, operatorIter, frame );
	}

	if ( !ok )
	{
		Error::Error_1017_UnexepectedCharInVariableValue( iter );
		return false;
	}

	bool result = false;

	// find closing token
	BFFIterator openTokenPos( iter );
	BFFIterator openTokenForError( iter ); // take note of opening token pos for possible error
	openTokenPos++; // more start iter to first char of value
	if ( openToken == BFF_SCOPE_OPEN )
	{
		if ( iter.ParseToMatchingBrace( openToken, closeToken ) )
		{
			result = StoreVariableArray( varName, openTokenPos, iter, operatorIter, frame );
		}
		else
		{
			Error::Error_1002_MatchingClosingTokenNotFound( openTokenForError, nullptr, closeToken );
		}
	}
	else if ( openToken == BFF_STRUCT_OPEN )
	{
		if ( iter.ParseToMatchingBrace( openToken, closeToken ) )
		{
			result = StoreVariableStruct( varName, openTokenPos, iter, operatorIter, frame );
		}
		else
		{
			Error::Error_1002_MatchingClosingTokenNotFound( openTokenForError, nullptr, closeToken );
		}
	}
	else
	{
		ASSERT( ( openToken == '\'' ) || ( openToken == '"' ) );
		iter.SkipString( closeToken );
		if ( *iter == closeToken )
		{
			result = StoreVariableString( varName, openTokenPos, iter, operatorIter, frame );
		}
		else		
		{
			Error::Error_1002_MatchingClosingTokenNotFound( openTokenForError, nullptr, closeToken );
		}
	}

	if ( result )
	{
		iter++; // skip over the end token
	}

	// StoreVariable will have emitted an error if there was one
	return result;
}
Esempio n. 2
0
// ParseNamedVariableName
//------------------------------------------------------------------------------
/*static*/ bool BFFParser::ParseVariableName( BFFIterator & iter, AString & name, bool & parentScope )
{
	// skip over the declaration symbol
	ASSERT( *iter == BFF_DECLARE_VAR_INTERNAL ||
			*iter == BFF_DECLARE_VAR_PARENT );

	parentScope = ( *iter == BFF_DECLARE_VAR_PARENT );

	const BFFIterator varNameStart = iter; // include type token in var name
	iter++;

	// make sure we haven't hit the end of the file
	if ( iter.IsAtEnd() )
	{
		Error::Error_1012_UnexpectedEndOfFile( iter );
		return false;
	}

	if ( *iter == '\'' || *iter == '"' )
	{
		// parse the string
		const BFFIterator openToken = iter;
		iter.SkipString( *openToken );
		if ( *iter != *openToken )
		{
			Error::Error_1002_MatchingClosingTokenNotFound( openToken, nullptr, *openToken );
			return false;
		}
		BFFIterator stringStart = openToken;
		stringStart++;

		// unescape and subsitute embedded variables
		AStackString< 256 > value;
		if ( PerformVariableSubstitutions( stringStart, iter, value ) == false )
		{
			return false;
		}
		iter++; // skip close token

		BFFIterator varNameIter( value.Get(), value.GetLength(), iter.GetFileName().Get(), iter.GetFileTimeStamp() );

		// sanity check it is a sensible length
		if ( value.GetLength() + 1/* '.' will be added */  > MAX_VARIABLE_NAME_LENGTH )
		{
			Error::Error_1014_VariableNameIsTooLong( varNameIter, (uint32_t)value.GetLength(), (uint32_t)MAX_VARIABLE_NAME_LENGTH );
			return false;
		}

		// sanity check it is a valid variable name
		while ( varNameIter.IsAtEnd() == false )
		{
			if ( varNameIter.IsAtValidVariableNameCharacter() == false )
			{
				Error::Error_1013_UnexpectedCharInVariableName( varNameIter, nullptr );
				return false;
			}
			varNameIter++;
		}

		// append '.' to variable name
		name = ".";
		name.Append( value );
	}
	else
	{
		// make sure immediately after the symbol starts a variable name
		if ( iter.IsAtValidVariableNameCharacter() == false )
		{
			Error::Error_1013_UnexpectedCharInVariableName( iter, nullptr );
			return false;
		}

		// find the end of the variable name
		iter.SkipVariableName();
		const BFFIterator varNameEnd = iter;

		// sanity check it is a sensible length
		size_t varNameLen = varNameStart.GetDistTo( varNameEnd );
		if ( varNameLen > MAX_VARIABLE_NAME_LENGTH )
		{
			Error::Error_1014_VariableNameIsTooLong( iter, (uint32_t)varNameLen, (uint32_t)MAX_VARIABLE_NAME_LENGTH );
			return false;
		}

		// store variable name
		name.Assign( varNameStart.GetCurrent(), varNameEnd.GetCurrent() );
	}

	ASSERT( name.GetLength() > 0 );
	if ( parentScope )
	{
		// exchange '^' with '.'
		ASSERT( BFF_DECLARE_VAR_PARENT == name[0] );
		name[0] = BFF_DECLARE_VAR_INTERNAL;
	}

	return true;
}