示例#1
0
    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;
    }
示例#2
0
    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);
    }
示例#3
0
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;
}
示例#4
0
    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);
    }