bool Parser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (!(mOptional && mEmpty)) reportSeriousError ("Unexpected special token", loc); else scanner.putbackSpecial (code, loc); return false; }
bool LineParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (code==Scanner::S_newline && (mState==EndState || mState==BeginState || mState==PotentialEndState)) return false; if (code==Scanner::S_comma && mState==MessageState) { mState = MessageCommaState; return true; } if (code==Scanner::S_ref && mState==PotentialExplicitState) { mState = ExplicitState; return true; } if (code==Scanner::S_member && mState==PotentialExplicitState) { mState = MemberState; parseExpression (scanner, loc); mState = EndState; return true; } if (code==Scanner::S_newline && mState==MessageButtonState) { Generator::message (mCode, mLiterals, mName, mButtons); return false; } if (code==Scanner::S_comma && mState==MessageButtonState) { mState = MessageButtonCommaState; return true; } if (code==Scanner::S_member && mState==SetPotentialMemberVarState) { mState = SetMemberVarState; return true; } if (mAllowExpression && mState==BeginState && (code==Scanner::S_open || code==Scanner::S_minus)) { scanner.putbackSpecial (code, loc); parseExpression (scanner, loc); mState = EndState; return true; } return Parser::parseSpecial (code, loc, scanner); }
bool ScriptParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) { if (code==Scanner::S_newline) // empty line return true; if (code==Scanner::S_open) /// \todo Option to switch this off { scanner.putbackSpecial (code, loc); return parseKeyword (Scanner::K_if, loc, scanner); } mLineParser.reset(); if (mLineParser.parseSpecial (code, loc, scanner)) scanner.scan (mLineParser); 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); }