bool Parser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (!(mOptional && mEmpty)) reportSeriousError ("Unexpected keyword", loc); else scanner.putbackKeyword (keyword, loc); return false; }
bool Compiler::QuickFileParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (keyword==Scanner::K_end) return false; if (keyword==Scanner::K_short || keyword==Scanner::K_long || keyword==Scanner::K_float) { mDeclarationParser.reset(); scanner.putbackKeyword (keyword, loc); scanner.scan (mDeclarationParser); return true; } SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return true; }
bool ExprParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (!mExplicit.empty()) { if (mRefOp && code==Scanner::S_open) { /// \todo add option to disable this workaround mOperators.push_back ('('); mTokenLoc = loc; return true; } if (!mRefOp && code==Scanner::S_ref) { mRefOp = true; return true; } if (!mMemberOp && code==Scanner::S_member) { mMemberOp = true; return true; } return Parser::parseSpecial (code, loc, scanner); } if (code==Scanner::S_comma) { mTokenLoc = loc; if (mFirst) { // leading comma mFirst = false; return true; } // end marker scanner.putbackSpecial (code, loc); return false; } mFirst = false; if (code==Scanner::S_newline) { // end marker mTokenLoc = loc; scanner.putbackSpecial (code, loc); return false; } if (code==Scanner::S_minus && mNextOperand) { // unary mOperators.push_back ('m'); mTokenLoc = loc; return true; } if (code==Scanner::S_open) { if (mNextOperand) { mOperators.push_back ('('); mTokenLoc = loc; return true; } else { // no comma was used between arguments scanner.putbackKeyword (code, loc); return false; } } if (code==Scanner::S_close && !mNextOperand) { if (isOpen()) { close(); return true; } mTokenLoc = loc; scanner.putbackSpecial (code, loc); return false; } if (!mNextOperand) { mTokenLoc = loc; char c = 0; // comparison switch (code) { case Scanner::S_plus: c = '+'; break; case Scanner::S_minus: c = '-'; break; case Scanner::S_mult: pushBinaryOperator ('*'); return true; case Scanner::S_div: pushBinaryOperator ('/'); return true; case Scanner::S_cmpEQ: c = 'e'; break; case Scanner::S_cmpNE: c = 'n'; break; case Scanner::S_cmpLT: c = 'l'; break; case Scanner::S_cmpLE: c = 'L'; break; case Scanner::S_cmpGT: c = 'g'; break; case Scanner::S_cmpGE: c = 'G'; break; } if (c) { if (mArgument && !isOpen()) { // expression ends here // Thank you Morrowind for this rotten syntax :( scanner.putbackSpecial (code, loc); return false; } pushBinaryOperator (c); return true; } } return Parser::parseSpecial (code, loc, scanner); }
bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (const Extensions *extensions = getContext().getExtensions()) { std::string argumentType; // ignored bool hasExplicit = false; // ignored if (extensions->isInstruction (keyword, argumentType, hasExplicit)) { // pretend this is not a keyword return parseName (loc.mLiteral, loc, scanner); } } if (keyword==Scanner::K_end || keyword==Scanner::K_begin || keyword==Scanner::K_short || keyword==Scanner::K_long || keyword==Scanner::K_float || keyword==Scanner::K_if || keyword==Scanner::K_endif || keyword==Scanner::K_else || keyword==Scanner::K_elseif || keyword==Scanner::K_while || keyword==Scanner::K_endwhile || keyword==Scanner::K_return || keyword==Scanner::K_messagebox || keyword==Scanner::K_set || keyword==Scanner::K_to || keyword==Scanner::K_startscript || keyword==Scanner::K_stopscript || keyword==Scanner::K_enable || keyword==Scanner::K_disable) { return parseName (loc.mLiteral, loc, scanner); } mFirst = false; if (!mExplicit.empty()) { if (mRefOp && mNextOperand) { if (keyword==Scanner::K_getdisabled) { start(); mTokenLoc = loc; Generator::getDisabled (mCode, mLiterals, mExplicit); mOperands.push_back ('l'); mExplicit.clear(); mRefOp = false; mNextOperand = false; return true; } else if (keyword==Scanner::K_getdistance) { start(); mTokenLoc = loc; parseArguments ("c", scanner); Generator::getDistance (mCode, mLiterals, mExplicit); mOperands.push_back ('f'); mExplicit.clear(); mRefOp = false; mNextOperand = false; return true; } // check for custom extensions if (const Extensions *extensions = getContext().getExtensions()) { char returnType; std::string argumentType; bool hasExplicit = true; if (extensions->isFunction (keyword, returnType, argumentType, hasExplicit)) { if (!hasExplicit) { getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); mExplicit.clear(); } start(); mTokenLoc = loc; int optionals = parseArguments (argumentType, scanner); extensions->generateFunctionCode (keyword, mCode, mLiterals, mExplicit, optionals); mOperands.push_back (returnType); mExplicit.clear(); mRefOp = false; mNextOperand = false; return true; } } } return Parser::parseKeyword (keyword, loc, scanner); } if (mNextOperand) { if (keyword==Scanner::K_getsquareroot) { start(); mTokenLoc = loc; parseArguments ("f", scanner); Generator::squareRoot (mCode); mOperands.push_back ('f'); mNextOperand = false; return true; } else if (keyword==Scanner::K_menumode) { start(); mTokenLoc = loc; Generator::menuMode (mCode); mOperands.push_back ('l'); mNextOperand = false; return true; } else if (keyword==Scanner::K_random) { start(); mTokenLoc = loc; parseArguments ("l", scanner); Generator::random (mCode); mOperands.push_back ('l'); mNextOperand = false; return true; } else if (keyword==Scanner::K_scriptrunning) { start(); mTokenLoc = loc; parseArguments ("c", scanner); Generator::scriptRunning (mCode); mOperands.push_back ('l'); mNextOperand = false; return true; } else if (keyword==Scanner::K_getdistance) { start(); mTokenLoc = loc; parseArguments ("c", scanner); Generator::getDistance (mCode, mLiterals, ""); mOperands.push_back ('f'); mNextOperand = false; return true; } else if (keyword==Scanner::K_getsecondspassed) { start(); mTokenLoc = loc; Generator::getSecondsPassed (mCode); mOperands.push_back ('f'); mNextOperand = false; return true; } else if (keyword==Scanner::K_getdisabled) { start(); mTokenLoc = loc; Generator::getDisabled (mCode, mLiterals, ""); mOperands.push_back ('l'); mNextOperand = false; return true; } else { // check for custom extensions if (const Extensions *extensions = getContext().getExtensions()) { start(); char returnType; std::string argumentType; bool hasExplicit = false; if (extensions->isFunction (keyword, returnType, argumentType, hasExplicit)) { mTokenLoc = loc; int optionals = parseArguments (argumentType, scanner); extensions->generateFunctionCode (keyword, mCode, mLiterals, "", optionals); mOperands.push_back (returnType); mNextOperand = false; return true; } } } } else { // no comma was used between arguments scanner.putbackKeyword (keyword, loc); return false; } return Parser::parseKeyword (keyword, loc, scanner); }
bool LineParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (mState==SetMemberVarState) { mMemberName = loc.mLiteral; std::pair<char, bool> type = getContext().getMemberType (mMemberName, mName); if (type.first!=' ') { mState = SetMemberVarState2; mType = type.first; mReferenceMember = type.second; return true; } } if (mState==SetPotentialMemberVarState && keyword==Scanner::K_to) { getErrorHandler().warning ("unknown variable (ignoring set instruction)", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; } if (mState==SetState) { // allow keywords to be used as variable names when assigning a value to a variable. return parseName (loc.mLiteral, loc, scanner); } if (mState==BeginState || mState==ExplicitState) { switch (keyword) { case Scanner::K_enable: Generator::enable (mCode, mLiterals, mExplicit); mState = PotentialEndState; return true; case Scanner::K_disable: Generator::disable (mCode, mLiterals, mExplicit); mState = PotentialEndState; return true; case Scanner::K_startscript: mExprParser.parseArguments ("c", scanner, mCode); Generator::startScript (mCode, mLiterals, mExplicit); mState = EndState; return true; case Scanner::K_stopscript: mExprParser.parseArguments ("c", scanner, mCode); Generator::stopScript (mCode); mState = EndState; return true; } // check for custom extensions if (const Extensions *extensions = getContext().getExtensions()) { std::string argumentType; bool hasExplicit = mState==ExplicitState; if (extensions->isInstruction (keyword, argumentType, hasExplicit)) { if (!hasExplicit && mState==ExplicitState) { getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); mExplicit.clear(); } int optionals = 0; try { // workaround for broken positioncell instructions. /// \todo add option to disable this std::auto_ptr<ErrorDowngrade> errorDowngrade (0); if (Misc::StringUtils::lowerCase (loc.mLiteral)=="positioncell") errorDowngrade.reset (new ErrorDowngrade (getErrorHandler())); std::vector<Interpreter::Type_Code> code; optionals = mExprParser.parseArguments (argumentType, scanner, code); mCode.insert (mCode.end(), code.begin(), code.end()); extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit, optionals); } catch (const SourceException& exception) { // Ignore argument exceptions for positioncell. /// \todo add option to disable this if (Misc::StringUtils::lowerCase (loc.mLiteral)=="positioncell") { SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return false; } throw; } mState = EndState; return true; } } if (mAllowExpression) { if (keyword==Scanner::K_getdisabled || keyword==Scanner::K_getdistance) { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); mState = EndState; return true; } if (const Extensions *extensions = getContext().getExtensions()) { char returnType; std::string argumentType; bool hasExplicit = !mExplicit.empty(); if (extensions->isFunction (keyword, returnType, argumentType, hasExplicit)) { if (!hasExplicit && !mExplicit.empty()) { getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); mExplicit.clear(); } scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); mState = EndState; return true; } } } } if (mState==ExplicitState) { // drop stray explicit reference getErrorHandler().warning ("stray explicit reference (ignoring it)", loc); mState = BeginState; mExplicit.clear(); } if (mState==BeginState) { switch (keyword) { case Scanner::K_short: case Scanner::K_long: case Scanner::K_float: { if (!getContext().canDeclareLocals()) { getErrorHandler().error ( "local variables can't be declared in this context", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); return true; } DeclarationParser declaration (getErrorHandler(), getContext(), mLocals); if (declaration.parseKeyword (keyword, loc, scanner)) scanner.scan (declaration); return false; } case Scanner::K_set: mState = SetState; return true; case Scanner::K_messagebox: mState = MessageState; return true; case Scanner::K_return: Generator::exit (mCode); mState = EndState; return true; case Scanner::K_stopscript: mExprParser.parseArguments ("c", scanner, mCode); Generator::stopScript (mCode); mState = EndState; return true; case Scanner::K_else: getErrorHandler().warning ("stray else (ignoring it)", loc); mState = EndState; return true; case Scanner::K_endif: getErrorHandler().warning ("stray endif (ignoring it)", loc); mState = EndState; return true; case Scanner::K_begin: getErrorHandler().warning ("stray begin (ignoring it)", loc); mState = EndState; return true; } } else if (mState==SetLocalVarState && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); std::vector<Interpreter::Type_Code> code; char type = mExprParser.append (code); Generator::assignToLocal (mCode, mLocals.getType (mName), mLocals.getIndex (mName), code, type); mState = EndState; return true; } else if (mState==SetGlobalVarState && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); std::vector<Interpreter::Type_Code> code; char type = mExprParser.append (code); Generator::assignToGlobal (mCode, mLiterals, mType, mName, code, type); mState = EndState; return true; } else if (mState==SetMemberVarState2 && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); std::vector<Interpreter::Type_Code> code; char type = mExprParser.append (code); Generator::assignToMember (mCode, mLiterals, mType, mMemberName, mName, code, type, !mReferenceMember); mState = EndState; return true; } if (mAllowExpression) { if (keyword==Scanner::K_getsquareroot || keyword==Scanner::K_menumode || keyword==Scanner::K_random || keyword==Scanner::K_scriptrunning || keyword==Scanner::K_getsecondspassed) { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); mState = EndState; return true; } } return Parser::parseKeyword (keyword, loc, scanner); }
bool LineParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { if (mState==BeginState || mState==ExplicitState) { switch (keyword) { case Scanner::K_enable: Generator::enable (mCode, mLiterals, mExplicit); mState = EndState; return true; case Scanner::K_disable: Generator::disable (mCode, mLiterals, mExplicit); mState = EndState; return true; } // check for custom extensions if (const Extensions *extensions = getContext().getExtensions()) { std::string argumentType; if (extensions->isInstruction (keyword, argumentType, mState==ExplicitState)) { int optionals = mExprParser.parseArguments (argumentType, scanner, mCode, true); extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit, optionals); mState = EndState; return true; } } if (mAllowExpression) { if (keyword==Scanner::K_getdisabled || keyword==Scanner::K_getdistance) { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); mState = EndState; return true; } if (const Extensions *extensions = getContext().getExtensions()) { char returnType; std::string argumentType; if (extensions->isFunction (keyword, returnType, argumentType, !mExplicit.empty())) { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); mState = EndState; return true; } } } } if (mState==BeginState) { switch (keyword) { case Scanner::K_short: mState = ShortState; return true; case Scanner::K_long: mState = LongState; return true; case Scanner::K_float: mState = FloatState; return true; case Scanner::K_set: mState = SetState; return true; case Scanner::K_messagebox: mState = MessageState; return true; case Scanner::K_return: Generator::exit (mCode); mState = EndState; return true; case Scanner::K_startscript: mExprParser.parseArguments ("c", scanner, mCode, true); Generator::startScript (mCode); mState = EndState; return true; case Scanner::K_stopscript: mExprParser.parseArguments ("c", scanner, mCode, true); Generator::stopScript (mCode); mState = EndState; return true; } } else if (mState==SetLocalVarState && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); std::vector<Interpreter::Type_Code> code; char type = mExprParser.append (code); Generator::assignToLocal (mCode, mLocals.getType (mName), mLocals.getIndex (mName), code, type); mState = EndState; return true; } else if (mState==SetGlobalVarState && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); std::vector<Interpreter::Type_Code> code; char type = mExprParser.append (code); Generator::assignToGlobal (mCode, mLiterals, mType, mName, code, type); mState = EndState; return true; } else if (mState==SetMemberVarState2 && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); std::vector<Interpreter::Type_Code> code; char type = mExprParser.append (code); Generator::assignToMember (mCode, mLiterals, mType, mMemberName, mName, code, type); mState = EndState; return true; } if (mAllowExpression) { if (keyword==Scanner::K_getsquareroot || keyword==Scanner::K_menumode || keyword==Scanner::K_random || keyword==Scanner::K_scriptrunning || keyword==Scanner::K_getsecondspassed) { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); mState = EndState; return true; } } return Parser::parseKeyword (keyword, loc, scanner); }
bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) { mFirst = false; if (!mExplicit.empty()) { if (mRefOp && mNextOperand) { if (keyword==Scanner::K_getdisabled) { mTokenLoc = loc; Generator::getDisabled (mCode, mLiterals, mExplicit); mOperands.push_back ('l'); mExplicit.clear(); mRefOp = false; mNextOperand = false; return true; } else if (keyword==Scanner::K_getdistance) { mTokenLoc = loc; parseArguments ("c", scanner); Generator::getDistance (mCode, mLiterals, mExplicit); mOperands.push_back ('f'); mExplicit.clear(); mRefOp = false; mNextOperand = false; return true; } // check for custom extensions if (const Extensions *extensions = getContext().getExtensions()) { char returnType; std::string argumentType; if (extensions->isFunction (keyword, returnType, argumentType, true)) { mTokenLoc = loc; parseArguments (argumentType, scanner); extensions->generateFunctionCode (keyword, mCode, mLiterals, mExplicit); mOperands.push_back (returnType); mExplicit.clear(); mRefOp = false; mNextOperand = false; return true; } } } return Parser::parseKeyword (keyword, loc, scanner); } if (mNextOperand) { if (keyword==Scanner::K_getsquareroot) { mTokenLoc = loc; parseArguments ("f", scanner); Generator::squareRoot (mCode); mOperands.push_back ('f'); mNextOperand = false; return true; } else if (keyword==Scanner::K_menumode) { mTokenLoc = loc; Generator::menuMode (mCode); mOperands.push_back ('l'); mNextOperand = false; return true; } else if (keyword==Scanner::K_random) { mTokenLoc = loc; parseArguments ("l", scanner); Generator::random (mCode); mOperands.push_back ('l'); mNextOperand = false; return true; } else if (keyword==Scanner::K_scriptrunning) { mTokenLoc = loc; parseArguments ("c", scanner); Generator::scriptRunning (mCode); mOperands.push_back ('l'); mNextOperand = false; return true; } else if (keyword==Scanner::K_getdistance) { mTokenLoc = loc; parseArguments ("c", scanner); Generator::getDistance (mCode, mLiterals, ""); mOperands.push_back ('f'); mNextOperand = false; return true; } else if (keyword==Scanner::K_getsecondspassed) { mTokenLoc = loc; Generator::getSecondsPassed (mCode); mOperands.push_back ('f'); mNextOperand = false; return true; } else if (keyword==Scanner::K_getdisabled) { mTokenLoc = loc; Generator::getDisabled (mCode, mLiterals, ""); mOperands.push_back ('l'); mNextOperand = false; return true; } else { // check for custom extensions if (const Extensions *extensions = getContext().getExtensions()) { char returnType; std::string argumentType; if (extensions->isFunction (keyword, returnType, argumentType, false)) { mTokenLoc = loc; parseArguments (argumentType, scanner); extensions->generateFunctionCode (keyword, mCode, mLiterals, ""); mOperands.push_back (returnType); mNextOperand = false; return true; } } } } else { // no comma was used between arguments scanner.putbackKeyword (keyword, loc); return false; } return Parser::parseKeyword (keyword, loc, scanner); }