Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}