static bool parseSexp(Game& game, sexp_t* expression) { sexp_t* sub, *subsub; if( !expression ) return false; expression = expression->list; if( !expression ) return false; if(expression->val != NULL && strcmp(expression->val, "status") == 0) { GameState gs; while(expression->next != NULL) { expression = expression->next; sub = expression->list; if ( !sub ) return false; if(string(sub->val) == "game") { sub = sub->next; if ( !sub ) return false; gs.mapWidth = atoi(sub->val); sub = sub->next; if ( !sub ) return false; gs.mapHeight = atoi(sub->val); sub = sub->next; if ( !sub ) return false; gs.waterDamage = atoi(sub->val); sub = sub->next; if ( !sub ) return false; gs.turnNumber = atoi(sub->val); sub = sub->next; if ( !sub ) return false; gs.maxUnits = atoi(sub->val); sub = sub->next; if ( !sub ) return false; gs.playerID = atoi(sub->val); sub = sub->next; if ( !sub ) return false; gs.gameNumber = atoi(sub->val); sub = sub->next; if ( !sub ) return false; gs.maxSiege = atoi(sub->val); sub = sub->next; if ( !sub ) return false; gs.oxygenRate = atof(sub->val); sub = sub->next; if ( !sub ) return false; gs.depositionRate = atoi(sub->val); sub = sub->next; } else if(string(sub->val) == "Player") { sub = sub->next; bool flag = true; while(sub && flag) { Player object; flag = parsePlayer(object, sub); gs.players[object.id] = object; sub = sub->next; } if ( !flag ) return false; } else if(string(sub->val) == "Mappable") { sub = sub->next; bool flag = true; while(sub && flag) { Mappable object; flag = parseMappable(object, sub); gs.mappables[object.id] = object; sub = sub->next; } if ( !flag ) return false; } else if(string(sub->val) == "PumpStation") { sub = sub->next; bool flag = true; while(sub && flag) { PumpStation object; flag = parsePumpStation(object, sub); gs.pumpStations[object.id] = object; sub = sub->next; } if ( !flag ) return false; } else if(string(sub->val) == "Unit") { sub = sub->next; bool flag = true; while(sub && flag) { Unit object; flag = parseUnit(object, sub); gs.units[object.id] = object; sub = sub->next; } if ( !flag ) return false; } else if(string(sub->val) == "Tile") { sub = sub->next; bool flag = true; while(sub && flag) { Tile object; flag = parseTile(object, sub); gs.tiles[object.id] = object; sub = sub->next; } if ( !flag ) return false; } else if(string(sub->val) == "UnitType") { sub = sub->next; bool flag = true; while(sub && flag) { UnitType object; flag = parseUnitType(object, sub); gs.unitTypes[object.id] = object; sub = sub->next; } if ( !flag ) return false; } } game.states.push_back(gs); } else if(string(expression->val) == "animations") { std::map< int, std::vector< SmartPointer< Animation > > > animations; while(expression->next) { expression = expression->next; sub = expression->list; if ( !sub ) return false; if(string(ToLower( sub->val ) ) == "dig") { SmartPointer<dig> animation = new dig; if ( !parseDig(*animation, expression) ) return false; animations[ ((AnimOwner*)&*animation)->owner ].push_back( animation ); } if(string(ToLower( sub->val ) ) == "attack") { SmartPointer<attack> animation = new attack; if ( !parseAttack(*animation, expression) ) return false; animations[ ((AnimOwner*)&*animation)->owner ].push_back( animation ); } if(string(ToLower( sub->val ) ) == "spawn") { SmartPointer<spawn> animation = new spawn; if ( !parseSpawn(*animation, expression) ) return false; animations[ ((AnimOwner*)&*animation)->owner ].push_back( animation ); } if(string(ToLower( sub->val ) ) == "death") { SmartPointer<death> animation = new death; if ( !parseDeath(*animation, expression) ) return false; animations[ ((AnimOwner*)&*animation)->owner ].push_back( animation ); } if(string(ToLower( sub->val ) ) == "move") { SmartPointer<move> animation = new move; if ( !parseMove(*animation, expression) ) return false; animations[ ((AnimOwner*)&*animation)->owner ].push_back( animation ); } if(string(ToLower( sub->val ) ) == "flow") { SmartPointer<flow> animation = new flow; if ( !parseFlow(*animation, expression) ) return false; animations[ ((AnimOwner*)&*animation)->owner ].push_back( animation ); } if(string(ToLower( sub->val ) ) == "fill") { SmartPointer<fill> animation = new fill; if ( !parseFill(*animation, expression) ) return false; animations[ ((AnimOwner*)&*animation)->owner ].push_back( animation ); } } game.states[game.states.size()-1].animations = animations; } else if(string(expression->val) == "ident") { expression = expression->next; if ( !expression ) return false; sub = expression->list; while(sub) { subsub = sub->list; if ( !subsub ) return false; int number = atoi(subsub->val); if(number >= 0) { subsub = subsub->next; if ( !subsub ) return false; subsub = subsub->next; if ( !subsub ) return false; game.players[number] = subsub->val; } sub = sub->next; } } else if(string(expression->val) == "game-winner") { expression = expression->next; if ( !expression ) return false; expression = expression->next; if ( !expression ) return false; expression = expression->next; if ( !expression ) return false; game.winner = atoi(expression->val); expression = expression->next; if( !expression ) return false; game.winReason = expression->val; } return true; }
ParserNode* Parser::parseExpression(const list<LexerTreeItem*>& source, ParserVariables& vars) { vector<ParserItemWrapper> items; // Wrapping lexer primitives into parser ParserItemWrapper objects bool previousIsOperand = false; for (list<LexerTreeItem*>::const_iterator iter = source.begin(); iter != source.end(); iter++) { if ((*iter)->getInnerText() == "+") { items.push_back(ParserItemWrapper::withOperator(foAdd)); previousIsOperand = false; } else if ((*iter)->getInnerText() == "-") { if (previousIsOperand) { items.push_back(ParserItemWrapper::withOperator(foSubtract)); } else { items.push_back(ParserItemWrapper::withOperator(foNegate)); } previousIsOperand = false; } else if ((*iter)->getInnerText() == "*") { items.push_back(ParserItemWrapper::withOperator(foMultiply)); previousIsOperand = false; } else if ((*iter)->getInnerText() == "/") { items.push_back(ParserItemWrapper::withOperator(foDivide)); previousIsOperand = false; } else if ((*iter)->getInnerText() == "=") { items.push_back(ParserItemWrapper::withOperator(foEquate)); previousIsOperand = false; } else if ((*iter)->getOuterBraces() == brRound) { items.push_back(ParserItemWrapper::withOperand(parseExpression((*iter)->getInnerItems(), vars))); previousIsOperand = true; } else if ((*iter)->getOuterBraces() == brCurly) { items.push_back(ParserItemWrapper::withOperand(parseFlow((*iter)->getInnerItems(), vars))); previousIsOperand = true; } else if (ConstantParserNode::isDoubleConstant((*iter)->getInnerText())) { ConstantParserNode* cfi = new ConstantParserNode(ConstantParserNode::parseDouble((*iter)->getInnerText(), vars)); items.push_back(ParserItemWrapper::withOperand(cfi)); previousIsOperand = true; } else if (vars.contains((*iter)->getInnerText(), tDouble)) { VariableParserNode* vfi = new VariableParserNode((*iter)->getInnerText(), tDouble, vars); items.push_back(ParserItemWrapper::withOperand(vfi)); previousIsOperand = true; } else { throw InvalidTokenParserException((*iter)->getInnerText()); } } // Processing operators while (items.size() > 1) { size_t highest_priority_index = 0; int highest_priority = 0; for (size_t i = 0; i < items.size(); i++) { if (items[i].type == ParserItemWrapper::tOperator) { if (priorities.priorityOf(items[i].parserOperator) > highest_priority) { highest_priority = priorities.priorityOf(items[i].parserOperator); highest_priority_index = i; } } } if (items[highest_priority_index].parserOperator == foEquate) { // Assign operator if (highest_priority_index < 1 || items[highest_priority_index - 1].type != ParserItemWrapper::tOperand) { throw OperandWantedParserException(); } if (highest_priority_index > items.size() - 2 || items[highest_priority_index + 1].type != ParserItemWrapper::tOperand) { throw OperandWantedParserException(); } if (!items[highest_priority_index - 1].parserOperand->canBeAssigned()) { throw NotAssignableParserException(); } AssignmentOperationParserNode* fao = new AssignmentOperationParserNode(items[highest_priority_index - 1].parserOperand, items[highest_priority_index + 1].parserOperand, vars); items.erase(items.begin() + highest_priority_index + 1); items.erase(items.begin() + highest_priority_index); items[highest_priority_index - 1] = ParserItemWrapper::withOperand(fao); } else if (items[highest_priority_index].parserOperator == foNegate) { // Unary operators if (highest_priority_index > items.size() - 2 || items[highest_priority_index + 1].type != ParserItemWrapper::tOperand) { throw OperandWantedParserException(); } UnaryOperationParserNode* fuo = new UnaryOperationParserNode( items[highest_priority_index + 1].parserOperand, items[highest_priority_index].parserOperator, vars); items.erase(items.begin() + highest_priority_index + 1); items[highest_priority_index] = ParserItemWrapper::withOperand(fuo); } else { // Binary operators if (highest_priority_index < 1 || items[highest_priority_index - 1].type != ParserItemWrapper::tOperand) { throw OperandWantedParserException(); } if (highest_priority_index > items.size() - 2 || items[highest_priority_index + 1].type != ParserItemWrapper::tOperand) { throw OperandWantedParserException(); } if (items[highest_priority_index].parserOperator == foEquate) { if (!items[highest_priority_index - 1].parserOperand->canBeAssigned()) { throw NotAssignableParserException(); } } // Replacing the binary operation part with a single object BinaryOperationParserNode* fbo = new BinaryOperationParserNode(items[highest_priority_index - 1].parserOperand, items[highest_priority_index].parserOperator, items[highest_priority_index + 1].parserOperand, vars); items.erase(items.begin() + highest_priority_index + 1); items.erase(items.begin() + highest_priority_index); items[highest_priority_index - 1] = ParserItemWrapper::withOperand(fbo); } } if (items.front().type != ParserItemWrapper::tOperand) { throw OperandWantedParserException(); } return items.front().parserOperand; }