Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

KodeActionCreators.cc

Go to the documentation of this file.
00001 #include "Kodu/Parsing/Parser.h"
00002 
00003 namespace Kodu {
00004   KoduActionGive* Parser::KodeCreator::createGiveKode(std::vector<TokenBase*>& mods){
00005         
00006         
00007     return (new KoduActionGive());
00008   }
00009 
00010   KoduActionDrop* Parser::KodeCreator::createDropKode(std::vector<TokenBase*>& mods) {
00011     // ASSERTION: There are 1 - 2 modifiers
00012     PARSER_ASSERT((mods.size() == 0),
00013                   errorMessage << "The Drop action should have 0 tokens.");
00014 
00015     // create the action
00016     return (new KoduActionDrop());
00017   }
00018 
00019   KoduActionGrab* Parser::KodeCreator::createGrabKode(std::vector<TokenBase*>& mods) {
00020     //****** temp fix (need to find out how much are actualy used)
00021       // ASSERTION: There are 1 - 2 modifiers
00022       PARSER_ASSERT((0 <= mods.size() && mods.size() <= 2),
00023                     errorMessage << "The Grab action should have 1 - 2 tokens.");
00024     //******
00025 
00026         // Mandatory modifiers
00027         bool itModifierWasSpecified = false;
00028 
00029     // Optional modifiers
00030     bool onceEnabled = false;
00031 
00032     // checkers
00033     int tokenCount = 1;
00034 
00035     // parsing loop
00036     while (!mods.empty()) {
00037       // check if the token is a keyword
00038       if (mods[0]->isKeywordToken()) {
00039         std::string keyword = mods[0]->getKeywordData();
00040         if (keyword == "once") {        KoduState state;
00041 
00042           // ASSERTION: the once modifier was not already parsed
00043           PARSER_ASSERT((onceEnabled == false),
00044                         errorMessage << "Found a second once modifier (only one is allowed).");
00045           onceEnabled = true;
00046         }
00047 
00048         else if (keyword == "it") {
00049           // ASSERTION: the "it" modifier was not already parsed
00050           PARSER_ASSERT((itModifierWasSpecified == false),
00051                         errorMessage << "Found a second it modifier (only one is allowed).");
00052           itModifierWasSpecified = true;
00053         }
00054 
00055         else {
00056           // ASSERTION: "it" is the keyword
00057           PARSER_ASSERT((ERROR),
00058                         errorMessage << "The keyword \"" << keyword
00059                         << "\" cannot be used for the grab action.");
00060         }
00061       }
00062       // this is a serious error!!!
00063       else {
00064         // ASSERTION: There is an illegal token for this action
00065         PARSER_ASSERT((ERROR),
00066                       errorMessage << "Failed to recognize token " << tokenCount
00067                       << " for the grab action.");
00068       }
00069       // bookkeeping and prevents infinite loop
00070       GeneralFncs::destroyPtrInVector(mods, 0);
00071       tokenCount++;
00072     }
00073     if(itModifierWasSpecified == false)
00074       itModifierWasSpecified = true;
00075     // ASSERTION: the sound file was added
00076     /*
00077       PARSER_ASSERT((itModifierWasSpecified == true),
00078       errorMessage << "This Grab action does not have an it modifier!");
00079     */
00080     // create the action
00081     return (new KoduActionGrab(itModifierWasSpecified, onceEnabled));
00082   }
00083 
00084   KoduActionMotion* Parser::KodeCreator::createMoveKode(std::vector<TokenBase*>& mods) {
00085     // ASSERTION: There are
00086     PARSER_ASSERT((0 <= mods.size() && mods.size() <= 5),
00087                   errorMessage << "The Move action should only have 0 - 5 tokens.");
00088 
00089     // Optional modifiers
00090     KoduActionMotion::MotionType_t motionType = KoduActionMotion::MT_MOVE_GAMEPAD;
00091     KoduActionMotion::MotionRate_t motionRate;
00092     std::string tempMotionRate;
00093     unsigned int motionRateCount = 0;
00094 
00095     // checkers
00096     int tokenCount = 1;
00097     bool parsedMotionType = false;
00098     bool parsedMotionRate = false;
00099     bool parsedDriven = false;
00100         
00101     // parsing loop
00102     while (!mods.empty()) {
00103       // if it is a keyword
00104       if (mods[0]->isKeywordToken()) {
00105         std::string keyword = mods[0]->getKeywordData();
00106         // check if the keyword is a rate specifier
00107         if (keyword == "quickly" || keyword == "slowly") {
00108           if (parsedMotionRate) {
00109                                             
00110             motionType = KoduActionMotion::MT_MOVE_WANDER;
00111             PARSER_ASSERT((motionRateCount <= 3),
00112                           errorMessage << "The move action can only have up to 3 rate specifiers.\n");
00113 
00114             // ASSERTION: The user did not specify a different rate specifier
00115             PARSER_ASSERT((keyword == tempMotionRate),
00116                           errorMessage << "Different types of rate specifiers cannot be used.\n"
00117                           << "First type seen: " << tempMotionRate << "\nSecond type seen: "
00118                           << keyword);
00119           } else {
00120             tempMotionRate = keyword;
00121             parsedMotionRate = true;
00122           }
00123           // increment the number of rate specifiers seen
00124           motionRateCount++;
00125         }
00126                 
00127         else if (keyword == "move"){
00128           motionType = KoduActionMotion::MT_MOVE_GAMEPAD;
00129           parsedMotionType = true;
00130           parsedDriven = true;
00131         }
00132         // check if it is one of the move action's modifiers
00133         else if (keyword == "wander" || keyword == "forward" || keyword == "towards") {
00134           // ASSERTION: A motion type was not previously selected
00135           PARSER_ASSERT((parsedMotionType == false),
00136                         errorMessage << "A mowas already selected (There can only "
00137                         << "be one). Secowanderwandernd move type found: " << keyword << ".");
00138           PARSER_ASSERT((parsedDriven == false),
00139                         errorMessage << "A move type for this action cannot be executed");
00140           if (keyword == "wander")
00141             motionType = KoduActionMotion::MT_MOVE_WANDER;
00142           else if (keyword == "forward")
00143             motionType = KoduActionMotion::MT_MOVE_FORWARD;
00144           else if (keyword == "towards")
00145             motionType = KoduActionMotion::MT_MOVE_TOWARDS;
00146           parsedMotionType = true;
00147         }
00148         // user used the wrong keyword
00149         else {
00150           // ASSERTION: The user used the wrong keyword for this action
00151           PARSER_ASSERT((ERROR),
00152                         errorMessage << "The keyword \"" << keyword
00153                         << "\" cannot be used with the move action.");
00154         }
00155       }
00156       // user used the wrong token type
00157       else {
00158         // ASSERTION: The user used the wrong type of token with this action
00159         PARSER_ASSERT((ERROR),
00160                       errorMessage << "Token " << tokenCount << " is unrecognized and cannot be used "
00161                       << "with the move action.");
00162       }
00163             
00164       // bookkeeping
00165       GeneralFncs::destroyPtrInVector(mods, 0);
00166     }
00167     // check if a move type was specified
00168     if (!parsedMotionType) {
00169       motionType = KoduActionMotion::MT_MOVE_GAMEPAD;
00170     }
00171 
00172     // check if a rate specifier was specified
00173     if (!parsedMotionRate) {
00174       motionRate = KoduActionMotion::MR_NORMAL;
00175       motionRateCount = 1;
00176     } else {
00177       if (tempMotionRate == "quickly")
00178         motionRate = KoduActionMotion::MR_QUICKLY;
00179       else    
00180         motionRate = KoduActionMotion::MR_SLOWLY;
00181     }
00182   
00183     // create the action
00184     return (new KoduActionMotion(motionType, motionRate, motionRateCount));
00185   }
00186 
00187   KoduActionPlay* Parser::KodeCreator::createPlayKode(std::vector<TokenBase*>& mods) {
00188     // ASSERTION: There are 1 - 2 modifiers
00189     PARSER_ASSERT((1 <= mods.size() && mods.size() <= 2),
00190                   errorMessage << "The Play action should have 1 - 2 tokens.");
00191 
00192     // Mandatory modifiers
00193     std::string soundFile;
00194 
00195     // Optional modifiers
00196     bool onceEnabled = false;
00197 
00198     // checkers
00199     int tokenCount = 1;
00200 
00201     // parsing loop
00202     while (!mods.empty()) {
00203       // if it is a literal string
00204       if (mods[0]->isStringToken()) {
00205         // ASSERTION: The sound file was not assigned as yet
00206         PARSER_ASSERT((soundFile.empty()),
00207                       errorMessage << "Found a second sound file (only one is allowed).");
00208 
00209         // assign the sound file
00210         soundFile = mods[0]->getStringData();
00211       }
00212       // check if the token is a keyword
00213       else if (mods[0]->isKeywordToken()) {
00214         std::string keyword = mods[0]->getKeywordData();
00215         // ASSERTION: "once" is the keyword
00216         PARSER_ASSERT((keyword == "once"),
00217                       errorMessage << "The keyword \"" << keyword
00218                       << "\" cannot be used for this action.");
00219                 
00220         // ASSERTION: the once modifier was not already parsed
00221         PARSER_ASSERT((onceEnabled == false),
00222                       errorMessage << "Found a second once modifier (only one is allowed).");
00223         onceEnabled = true;
00224       }
00225       // this is a serious error!!!
00226       else {
00227         // ASSERTION: There is an illegal token for this action
00228         PARSER_ASSERT((ERROR),
00229                       errorMessage << "Failed to recognize token " << tokenCount
00230                       << " for the play action.");
00231       }
00232       // bookkeeping and prevents infinite loop
00233       GeneralFncs::destroyPtrInVector(mods, 0);
00234       tokenCount++;
00235     }
00236     // ASSERTION: the sound file was added
00237     PARSER_ASSERT((!soundFile.empty()),
00238                   errorMessage << "This Play action does not have a sound file to play!");
00239 
00240     // create the action
00241     LiteralGenerator playLiteral(soundFile, Kodu::LiteralGenerator::RO_SEQUENTIAL);
00242     return (new KoduActionPlay(playLiteral, onceEnabled));
00243   }
00244 
00245   KoduActionSay* Parser::KodeCreator::createSayKode(std::vector<TokenBase*>& mods) {
00246     // ASSERTION: There are 1 - 10 modifiers
00247     PARSER_ASSERT((1 <= mods.size() && mods.size() <= 10),
00248                   errorMessage << "The Say action should have 1 - 10 tokens.");
00249 
00250     // Mandatory modifiers
00251     std::vector<std::string> literalStrings;
00252 
00253     // Optional modifiers
00254     LiteralGenerator::ReturnOrder_t returnOrder;
00255     bool randomKeywordWasFound = false;
00256     bool onceEnabled = false;
00257     std::string color;
00258 
00259     // checkers
00260     int tokenCount = 1;
00261         
00262     // parsing loop
00263     while (!mods.empty()) {
00264       // check if the token is a string
00265       if (mods[0]->isStringToken()) {
00266         literalStrings.push_back(mods[0]->getStringData());
00267       }
00268       // check if the token is a keyword
00269       else if (mods[0]->isKeywordToken()) {
00270         std::string keyword = mods[0]->getKeywordData();
00271         // if the keyword is the once modifier
00272         if (keyword == "once") {
00273           // ASSERTION: The once modifier was not previously found
00274           PARSER_ASSERT((onceEnabled == false),
00275                         errorMessage << "Found a second \"once\" modifier (only one is allowed).");
00276           onceEnabled = true;
00277         }
00278         // check if the keyword is the random modifier
00279         else if (keyword == "random") {
00280           // ASSERTION: There is only one random keyword in this action phrase
00281           PARSER_ASSERT((randomKeywordWasFound == false),
00282                         errorMessage << "The \"random\" can only be used once in this phrase.");
00283           randomKeywordWasFound = true;
00284         }
00285         // check if the keyword is a color
00286         else if (Parser::isValidColor(keyword) != -1) {
00287           // ASSERTION: The color was not set
00288           PARSER_ASSERT((color.empty()),
00289                         errorMessage << "Found a second color (only one is allowed).");
00290           color = keyword;
00291         }
00292         // this is a serious error!!!
00293         else {
00294           // ASSERTION: There is an illegal token for this action
00295           PARSER_ASSERT((ERROR),
00296                         errorMessage << "Failed to recognize token " << tokenCount
00297                         << " for the play action.");
00298         }
00299       }
00300       // this is a serious error!!!
00301       else {
00302         // ASSERTION: There is an illegal token for this action
00303         PARSER_ASSERT((ERROR),
00304                       errorMessage << "Failed to recognize token " << tokenCount
00305                       << " for the play action.");
00306       }
00307       GeneralFncs::destroyPtrInVector(mods, 0);
00308       tokenCount++;
00309     }
00310     // ASSERTION: the literal string was specified
00311     PARSER_ASSERT((!literalStrings.empty()),
00312                   errorMessage << "This Say action does not have any strings to say!");
00313 
00314     // if the random keyword was not found, then speak the speech in sequential order
00315     if (randomKeywordWasFound)
00316       returnOrder = LiteralGenerator::RO_RANDOM;
00317     else
00318       returnOrder = LiteralGenerator::RO_SEQUENTIAL;
00319         
00320     // if a color was not assigned... assign a default color
00321     if (color.empty())
00322       color = Parser::koduDefaultDesignator;
00323 
00324     // create the action
00325     Kodu::LiteralGenerator sayLiterals(literalStrings, returnOrder);
00326     return (new KoduActionSay(color, sayLiterals, onceEnabled));
00327   }
00328 
00329   KoduActionScore* Parser::KodeCreator::createScoreKode(const std::string& scoreType,
00330                                                         std::vector<TokenBase*>& mods)
00331   {
00332     // ASSERTION: There are 0 - 5 modifiers
00333     PARSER_ASSERT((0 <= mods.size() && mods.size() <= 5),
00334                   errorMessage << "The Score action should have 0 - 5 tokens.");
00335 
00336     // Optional modifiers
00337     NumericGenerator tempNumGen(1, 0);
00338     bool onceEnabled = false;
00339     std::string scoreDesignator;
00340 
00341     // checkers
00342     int tokenCount = 1;
00343     bool designatorWasSet = false;
00344     bool handledNumerics = false;
00345 
00346     // get the score action type
00347     KoduActionScore::ScoringType_t scoreOp;
00348     if (scoreType == "score") {
00349       scoreOp = KoduActionScore::ST_SCORE;
00350     } else if (scoreType == "set_score") {
00351       scoreOp = KoduActionScore::ST_SET_SCORE;
00352     } else {
00353       scoreOp = KoduActionScore::ST_SUBTRACT;
00354     }
00355 
00356     // parsing loop
00357     while (!mods.empty()) {
00358       // check if the token is a numeric specifier
00359       if (isNumericSpecifier(mods[0])) {
00360         // ASSERTION: Numeric specifiers were not already handled/parsed
00361         PARSER_ASSERT((handledNumerics == false),
00362                       errorMessage << "Numeric specifiers for this action were already handled. "
00363                       << "Token " << tokenCount << " is illegal.");
00364         // get the numeric request
00365         // ASSERTION: The numeric/random number parser did not fail
00366         PARSER_ASSERT((numericGenParser(mods, tempNumGen) == true),
00367                       errorMessage << "An error occurred while parsing the numeric specifier token(s) "
00368                       << "(see above).");
00369         // note that numbers have been handled
00370         handledNumerics = true;
00371       }
00372       // check if the token is a keyword
00373       else if (mods[0]->isKeywordToken()) {
00374         std::string keyword = mods[0]->getKeywordData();
00375         // if the keyword is the once modifier
00376         if (keyword == "once") {
00377           // ASSERTION: The once modifier was not previously found
00378           PARSER_ASSERT((onceEnabled == false),
00379                         errorMessage << "Found a second \"once\" modifier (only one is allowed).");
00380           onceEnabled = true;
00381         }
00382         // check if the keyword is a score designator
00383         else if (isScoreDesignator(mods[0])) {
00384           // ASSERTION: The score designator was not set
00385           PARSER_ASSERT((designatorWasSet == false),
00386                         errorMessage << "Found a second score designator (only one is allowed).");
00387           scoreDesignator = keyword;
00388           designatorWasSet = true;
00389         }
00390         // this is a serious error!!!
00391         else {
00392           // ASSERTION: There is an illegal token for this action
00393           PARSER_ASSERT((ERROR),
00394                         errorMessage << "Failed to recognize token " << tokenCount
00395                         << " for the score/subtract/set score action.");
00396         }
00397         // bookkeeping
00398         GeneralFncs::destroyPtrInVector(mods, 0);
00399       }
00400       // this is a serious error!!!
00401       else {
00402         // ASSERTION: There is an illegal token for this action
00403         PARSER_ASSERT((ERROR),
00404                       errorMessage << "Failed to recognize token " << tokenCount
00405                       << " for the score/subtract/set score action.");
00406       }
00407       tokenCount++;
00408     }
00409     // assign the default color if no other designator was specified
00410     if (scoreDesignator.empty())
00411       scoreDesignator = Parser::koduDefaultDesignator;
00412     // create the action
00413     return (new KoduActionScore(scoreOp, tempNumGen, scoreDesignator, onceEnabled));
00414   }
00415 
00416   KoduActionMotion* Parser::KodeCreator::createTurnKode(std::vector<TokenBase*>& mods) {
00417     // ASSERTION: There are
00418     PARSER_ASSERT((0 <= mods.size() && mods.size() <= 5),
00419                   errorMessage << "The Turn action should only have 0 - 5 tokens.");
00420 
00421     // Optional modifiers
00422     KoduActionMotion::MotionType_t motionType;
00423     KoduActionMotion::MotionRate_t motionRate;
00424     Direction_t directionToFace;
00425     std::string tempMotionRate;
00426     unsigned int motionRateCount = 0;
00427 
00428     // checkers
00429     int tokenCount = 1;
00430     bool parsedMotionType = false;
00431     bool parsedMotionRate = false;
00432     bool parsedDirection = false;
00433 
00434     // parsing loop
00435     while (!mods.empty()) {
00436       // if it is a keyword
00437       if (mods[0]->isKeywordToken()) {
00438         std::string keyword = mods[0]->getKeywordData();
00439         // check if the keyword is a rate specifier
00440         if (keyword == "quickly" || keyword == "slowly") {
00441           if (parsedMotionRate) {
00442             // ASSERTION: This is not the fourth rate specifier parsed
00443             PARSER_ASSERT((motionRateCount <= 3),
00444                           errorMessage << "The turn action can only have up to 3 rate specifiers.\n");
00445 
00446             // ASSERTION: The user did not specify a different rate specifier
00447             PARSER_ASSERT((keyword == tempMotionRate),
00448                           errorMessage << "Different types of rate specifiers cannot be used.\n"
00449                           << "First type seen: " << tempMotionRate << "\nSecond type seen: "
00450                           << keyword);
00451           } else {
00452             tempMotionRate = keyword;
00453             parsedMotionRate = true;
00454           }
00455           // increment the number of rate specifiers seen
00456           motionRateCount++;
00457         }
00458         // check if it is one of the move action's modifiers
00459         else if (keyword == "left" || keyword == "right" || keyword == "direction") {
00460           // ASSERTION: A motion type was not previously selected
00461           PARSER_ASSERT((parsedMotionType == false),
00462                         errorMessage << "A turn type for this action was already selected (There can only "
00463                         << "be one). Second turn type found: " << keyword << ".");
00464           if (keyword == "left")
00465             motionType = KoduActionMotion::MT_TURN_LEFT;
00466           else if (keyword == "right")
00467             motionType = KoduActionMotion::MT_TURN_RIGHT;
00468           else
00469             motionType = KoduActionMotion::MT_TURN_DIRECTION;
00470           parsedMotionType = true;
00471         }
00472         // check if it is one of the directions
00473         else if (keyword == "east" || keyword == "north" || keyword == "south"
00474                  || keyword == "west")
00475           {
00476             // ASSERTION: the turn type was already parsed
00477             PARSER_ASSERT((parsedMotionType == true),
00478                           errorMessage << "The keyword \"direction\" must be specified before the "
00479                           << "direction specifier " << keyword << ".");
00480             // ASSERTION: the turn type is direction
00481             PARSER_ASSERT((motionType == KoduActionMotion::MT_TURN_DIRECTION),
00482                           errorMessage << "Direction specifiers such as " << keyword
00483                           << " can only be used with the turn modifier \"direction\".");
00484             // ASSERTION: a direction was not parsed already
00485             PARSER_ASSERT((parsedDirection == false),
00486                           errorMessage << "A direction type was already parsed. (There can only "
00487                           << "be one). Second direction type found: " << keyword << ".");
00488 
00489             if (keyword == "east")
00490               directionToFace = DT_EAST;
00491             else if (keyword == "north")
00492               directionToFace = DT_NORTH;
00493             else if (keyword == "south")
00494               directionToFace = DT_SOUTH;
00495             else
00496               directionToFace = DT_WEST;
00497             parsedDirection = true;
00498           }
00499         // user used the wrong keyword
00500         else {
00501           // ASSERTION: The user used the wrong keyword for this action
00502           PARSER_ASSERT((ERROR),
00503                         errorMessage << "The keyword \"" << keyword
00504                         << "\" cannot be used with the move action.");
00505         }
00506       }
00507       // user used the wrong token type
00508       else {
00509         // ASSERTION: The user used the wrong type of token with this action
00510         PARSER_ASSERT((ERROR),
00511                       errorMessage << "Token " << tokenCount << " is an unrecognized and cannot be used "
00512                       << "with the move action.");
00513       }
00514 
00515       // bookkeeping
00516       GeneralFncs::destroyPtrInVector(mods, 0);
00517     }
00518     // check if a move type was specified
00519     if (!parsedMotionType) {
00520       motionType = KoduActionMotion::MT_TURN_LEFT;
00521     }
00522 
00523     // check if a rate specifier was specified
00524     if (!parsedMotionRate) {
00525       motionRate = KoduActionMotion::MR_NORMAL;
00526       motionRateCount = 1;
00527     } else {
00528       if (tempMotionRate == "quickly")
00529         motionRate = KoduActionMotion::MR_QUICKLY;
00530       else    
00531         motionRate = KoduActionMotion::MR_SLOWLY;
00532     }
00533 
00534     if (motionType == KoduActionMotion::MT_TURN_DIRECTION) {
00535       PARSER_ASSERT((parsedDirection == true),
00536                     errorMessage << "A direction specifier such as north or east must be specified"
00537                     << "when using the direction modifier.");
00538 
00539       return (new KoduActionMotion(directionToFace, motionRate, motionRateCount));
00540     }
00541 
00542     // create the action
00543     return (new KoduActionMotion(motionType, motionRate, motionRateCount));
00544   }
00545 
00546 } // namespace

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:42 2016 by Doxygen 1.6.3