//========================================================================== // // 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); }
//========================================================================== // // 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); }
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; }
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; } } }
//-------------------------------------------------------------------------------------------------- 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); }