コード例 #1
0
        private static void ParsePrimary(ParseState state, Program program)
        {
            if (state.CurrentToken == TokenType.LParen)
            {
                state.Advance();

                ParseClause(state, program);

                state.ExpectToken(TokenType.RParen);
                state.Advance();
            }
            else
            {
                ParseExpression(state, program);

                if (state.IsCompOp)                 // expr op expr
                {
                    var inst = GetInstruction(state.CurrentToken);

                    state.Advance();

                    ParseExpression(state, program);

                    program.Emit(inst);
                }
                else if (state.IsSymbol("NOT"))                 // expr NOT IN (expr, expr, etc)
                {
                    state.Advance();
                    state.ExpectSymbol("IN");

                    ParseInValueList(state, program, true);
                }
                else if (state.IsSymbol("IN"))                 // expr IN (expr, expr, etc)
                {
                    ParseInValueList(state, program, false);
                }
                else if (state.IsSymbol("IS"))                 // expr IS [NOT] NULL
                {
                    state.Advance();

                    bool negate = false;

                    if (state.IsSymbol("NOT"))
                    {
                        negate = true;
                        state.Advance();
                    }

                    state.ExpectSymbol("NULL");
                    state.Advance();

                    program.Emit(negate ? Instruction.NotNull : Instruction.IsNull);
                }
                else
                {
                    throw SyntaxError(state.Index, "Expected expr, IN, or IS; got {0}",
                                      state.CurrentTokenString);
                }
            }
        }
コード例 #2
0
        private static void ParseInValueList(ParseState state, Program program, bool negate)
        {
            // Notice:
            // "x IN (a, b, c)" is equivalent to "x = a OR x = b OR x = c";
            // we compile this to: [expr Mark Exch {Dup expr IsEq Exch} Pop Or]
            // "x NOT IN (a,b,c)" is equivalent to "x <> a AND x <> b AND x <> c";
            // we compile this to: [expr Mark Exch {Dup expr NotEq Exch} Pop And]

            state.Advance();             // eat the "IN" token

            state.ExpectToken(TokenType.LParen);
            state.Advance();

            program.Emit(Instruction.Mark);
            program.Emit(Instruction.Exch);

            program.Emit(Instruction.Dup);
            ParseExpression(state, program);
            program.Emit(negate ? Instruction.NotEq : Instruction.IsEq);
            program.Emit(Instruction.Exch);

            while (state.IsToken(TokenType.Comma))
            {
                state.Advance();

                program.Emit(Instruction.Dup);
                ParseExpression(state, program);
                program.Emit(negate ? Instruction.NotEq : Instruction.IsEq);
                program.Emit(Instruction.Exch);
            }

            state.ExpectToken(TokenType.RParen);
            state.Advance();

            program.Emit(Instruction.Pop);
            program.Emit(negate ? Instruction.And : Instruction.Or);
        }