Esempio n. 1
0
    bool Parser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner)
    {
        if (!(mOptional && mEmpty))
            reportSeriousError ("Unexpected keyword", loc);
        else
            scanner.putbackKeyword (keyword, loc);

        return false;
    }
Esempio n. 2
0
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;
}
Esempio n. 3
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);
    }
Esempio n. 4
0
    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);
    }
Esempio n. 5
0
    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);
    }
Esempio n. 6
0
    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);
    }
Esempio n. 7
0
    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);
    }