예제 #1
0
//==========================================================================
//
// Reads an actor definition
//
//==========================================================================
static void ParseActor(FScanner &sc)
{
	PClassActor *info = NULL;
	Baggage bag;

	info = ParseActorHeader(sc, &bag);
	sc.MustGetToken('{');
	while (sc.MustGetAnyToken(), sc.TokenType != '}')
	{
		switch (sc.TokenType)
		{
		case TK_Action:
			ParseActionDef (sc, info);
			break;

		case TK_Const:
			ParseConstant (sc, &info->Symbols, info);
			break;

		case TK_Enum:
			ParseEnum (sc, &info->Symbols, info);
			break;

		case TK_Native:
			ParseNativeFunction (sc, info);
			break;

		case TK_Var:
			ParseUserVariable (sc, &info->Symbols, info);
			break;

		case TK_Identifier:
			ParseActorProperty(sc, bag);
			break;

		case TK_States:
			if (bag.StateSet) 
			{
				sc.ScriptMessage("'%s' contains multiple state declarations", bag.Info->TypeName.GetChars());
				FScriptPosition::ErrorCounter++;
			}
			ParseStates(sc, bag.Info, (AActor *)bag.Info->Defaults, bag);
			bag.StateSet = true;
			break;

		case '+':
		case '-':
			ParseActorFlag(sc, bag, sc.TokenType);
			break;

		default:
			sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->TypeName.GetChars());
			break;
		}
	}
	FinishActor(sc, info, bag);
	sc.SetCMode (false);
}
예제 #2
0
//==========================================================================
//
// Reads an actor definition
//
//==========================================================================
static void ParseActor(FScanner &sc)
{
	FActorInfo * info=NULL;
	Baggage bag;

	info = ParseActorHeader(sc, &bag);
	sc.MustGetToken('{');
	while (sc.MustGetAnyToken(), sc.TokenType != '}')
	{
		switch (sc.TokenType)
		{
		case TK_Action:
			ParseActionDef (sc, info->Class);
			break;

		case TK_Const:
			ParseConstant (sc, &info->Class->Symbols, info->Class);
			break;

		case TK_Enum:
			ParseEnum (sc, &info->Class->Symbols, info->Class);
			break;

		case TK_Native:
			ParseNativeVariable (sc, &info->Class->Symbols, info->Class);
			break;

		case TK_Var:
			ParseUserVariable (sc, &info->Class->Symbols, info->Class);
			break;

		case TK_Identifier:
			ParseActorProperty(sc, bag);
			break;

		case '+':
		case '-':
			ParseActorFlag(sc, bag, sc.TokenType);
			break;

		default:
			sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->Class->TypeName.GetChars());
			break;
		}
	}
	FinishActor(sc, info, bag);
	sc.SetCMode (false);
}
예제 #3
0
asCScriptNode *asCParser::ParseExprValue()
{
	asCScriptNode *node = new asCScriptNode(snExprValue);

	sToken t1;
	GetToken(&t1);
	RewindTo(&t1);

	if( t1.type == ttIdentifier || IsRealType(t1.type) )
	{
		if( IsFunctionCall() )
			node->AddChildLast(ParseFunctionCall());
		else
			node->AddChildLast(ParseIdentifier());
	}
	else if( t1.type == ttCast )
		node->AddChildLast(ParseCast());
	else if( IsConstant(t1.type) )
		node->AddChildLast(ParseConstant());
	else if( t1.type == ttOpenParanthesis )
	{
		GetToken(&t1);
		node->UpdateSourcePos(t1.pos, t1.length);

		node->AddChildLast(ParseAssignment());
		if( isSyntaxError ) return node;

		GetToken(&t1);
		if( t1.type != ttCloseParanthesis )
			Error(ExpectedToken(")").AddressOf(), &t1);

		node->UpdateSourcePos(t1.pos, t1.length);
	}
	else
		Error(TXT_EXPECTED_EXPRESSION_VALUE, &t1);

	return node;
}
예제 #4
0
void ParseDecorate (FScanner &sc)
{
	// Get actor class name.
	for(;;)
	{
		FScanner::SavedPos pos = sc.SavePos();
		if (!sc.GetToken ())
		{
			return;
		}
		switch (sc.TokenType)
		{
		case TK_Include:
		{
			sc.MustGetString();
			// This check needs to remain overridable for testing purposes.
			if (Wads.GetLumpFile(sc.LumpNum) == 0 && !Args->CheckParm("-allowdecoratecrossincludes"))
			{
				int includefile = Wads.GetLumpFile(Wads.CheckNumForFullName(sc.String, true));
				if (includefile != 0)
				{
					I_FatalError("File %s is overriding core lump %s.",
						Wads.GetWadFullName(includefile), sc.String);
				}
			}
			FScanner newscanner;
			newscanner.Open(sc.String);
			ParseDecorate(newscanner);
			break;
		}

		case TK_Const:
			ParseConstant (sc, &GlobalSymbols, NULL);
			break;

		case TK_Enum:
			ParseEnum (sc, &GlobalSymbols, NULL);
			break;

		case ';':
			// ';' is the start of a comment in the non-cmode parser which
			// is used to parse parts of the DECORATE lump. If we don't add 
			// a check here the user will only get weird non-informative
			// error messages if a semicolon is found.
			sc.ScriptError("Unexpected ';'");
			break;

		case TK_Identifier:
			// 'ACTOR' cannot be a keyword because it is also needed as a class identifier
			// so let's do a special case for this.
			if (sc.Compare("ACTOR"))
			{
				ParseActor (sc);
				break;
			}
			else if (sc.Compare("PICKUP"))
			{
				ParseOldDecoration (sc, DEF_Pickup);
				break;
			}
			else if (sc.Compare("BREAKABLE"))
			{
				ParseOldDecoration (sc, DEF_BreakableDecoration);
				break;
			}
			else if (sc.Compare("PROJECTILE"))
			{
				ParseOldDecoration (sc, DEF_Projectile);
				break;
			}
			else if (sc.Compare("DAMAGETYPE"))
			{
				ParseDamageDefinition(sc);
				break;
			}
		default:
			sc.RestorePos(pos);
			ParseOldDecoration(sc, DEF_Decoration);
			break;
		}
	}
}
예제 #5
0
//--------------------------------------------------------------------------------------------------
static void ProcessChar
(
    Parser_t* parserPtr,
    char c
)
//--------------------------------------------------------------------------------------------------
{
    switch (parserPtr->next)
    {
        case EXPECT_OBJECT_OR_ARRAY:

            // Throw away whitespace characters until '{' or '[' is found.
            if (c == '{')
            {
                PushContext(parserPtr, LE_JSON_CONTEXT_OBJECT, GetEventHandler(parserPtr));
                parserPtr->next = EXPECT_MEMBER_OR_OBJECT_END;
                Report(parserPtr, LE_JSON_OBJECT_START);
            }
            else if (c == '[')
            {
                PushContext(parserPtr, LE_JSON_CONTEXT_ARRAY, GetEventHandler(parserPtr));
                parserPtr->next = EXPECT_VALUE_OR_ARRAY_END;
                Report(parserPtr, LE_JSON_ARRAY_START);
            }
            else if (!isspace(c))
            {
                Error(parserPtr, LE_JSON_SYNTAX_ERROR, "Document must start with '{' or '['.");
            }
            return;

        case EXPECT_MEMBER_OR_OBJECT_END:

            // Throw away whitespace until a '"' or '}' is found.
            if (c == '}')   // Object end found.
            {
                Report(parserPtr, LE_JSON_OBJECT_END);
                PopContext(parserPtr);
            }
            else if (c == '"')  // Start of member name (string) found.
            {
                PushContext(parserPtr, LE_JSON_CONTEXT_MEMBER, GetEventHandler(parserPtr));
                parserPtr->next = EXPECT_STRING;
            }
            else if (!isspace(c))
            {
                Error(parserPtr,
                      LE_JSON_SYNTAX_ERROR,
                      "Expected end of object (}) or beginning of object member name (\").");
            }
            return;

        case EXPECT_COLON:

            // Throw away whitespace until a ':' is found.
            if (c == ':')
            {
                parserPtr->next = EXPECT_VALUE;
            }
            else if (!isspace(c))
            {
                Error(parserPtr,
                      LE_JSON_SYNTAX_ERROR,
                      "Expected ':' after object member name.");
            }
            return;

        case EXPECT_VALUE:

            ParseValue(parserPtr, c);
            return;

        case EXPECT_COMMA_OR_OBJECT_END:

            // Throw away whitespace until a ',' or '}' is found.
            if (c == '}')   // Object end found.
            {
                Report(parserPtr, LE_JSON_OBJECT_END);
                PopContext(parserPtr);
            }
            else if (c == ',')  // Comma separator found.
            {
                parserPtr->next = EXPECT_MEMBER;
            }
            else if (!isspace(c))
            {
                Error(parserPtr,
                      LE_JSON_SYNTAX_ERROR,
                      "Expected end of object (}) or beginning of object member name (\").");
            }
            return;

        case EXPECT_MEMBER:

            // Throw away whitespace until a '"' is found.
            if (c == '"')  // Start of member name (string) found.
            {
                PushContext(parserPtr, LE_JSON_CONTEXT_MEMBER, GetEventHandler(parserPtr));
                parserPtr->next = EXPECT_STRING;
            }
            else if (!isspace(c))
            {
                Error(parserPtr,
                      LE_JSON_SYNTAX_ERROR,
                      "Expected beginning of object member name (\").");
            }
            return;

        case EXPECT_VALUE_OR_ARRAY_END:

            if (c == ']')
            {
                Report(parserPtr, LE_JSON_ARRAY_END);
                PopContext(parserPtr);
            }
            else
            {
                ParseValue(parserPtr, c);
            }
            return;

        case EXPECT_COMMA_OR_ARRAY_END:

            // Throw away whitespace until a ',' or ']' is found.
            if (c == ']')   // Array end found.
            {
                Report(parserPtr, LE_JSON_ARRAY_END);
                PopContext(parserPtr);
            }
            else if (c == ',')  // Comma separator found.
            {
                parserPtr->next = EXPECT_VALUE;
            }
            else if (!isspace(c))
            {
                Error(parserPtr,
                      LE_JSON_SYNTAX_ERROR,
                      "Expected end of array (]) or a comma separator (,).");
            }
            return;

        case EXPECT_STRING:

            ParseString(parserPtr, c);
            return;

        case EXPECT_NUMBER:

            if ((c == '.') || isdigit(c))
            {
                AddToBuffer(parserPtr, c);
            }
            else
            {
                ProcessNumber(parserPtr);
                ProcessChar(parserPtr, c);
            }
            return;

        case EXPECT_TRUE:

            ParseConstant(parserPtr, c, "true");
            if (strcmp(parserPtr->buffer, "true") == 0)
            {
                Report(parserPtr, LE_JSON_TRUE);
                PopContext(parserPtr);
            }
            return;

        case EXPECT_FALSE:

            ParseConstant(parserPtr, c, "false");
            if (strcmp(parserPtr->buffer, "false") == 0)
            {
                Report(parserPtr, LE_JSON_FALSE);
                PopContext(parserPtr);
            }
            return;

        case EXPECT_NULL:

            ParseConstant(parserPtr, c, "null");
            if (strcmp(parserPtr->buffer, "null") == 0)
            {
                Report(parserPtr, LE_JSON_NULL);
                PopContext(parserPtr);
            }
            return;

        case EXPECT_NOTHING:    ///< Parsing stopped.
            return;
    }

    LE_FATAL("Internal error: Invalid JSON parser expectation %d.", parserPtr->next);
}