Example #1
0
        private FunctionOperator GetFunctionOperator(Yytoken op)
        {
            switch (op.Type)
            {
            case TokenType.OP_LIKE: return(FunctionOperator.Like);

            case TokenType.OP_IN: return(FunctionOperator.In);

            case TokenType.FN_TRIM: return(FunctionOperator.Trim);

            case TokenType.FN_LEN: return(FunctionOperator.Len);

            case TokenType.FN_LEFT: return(FunctionOperator.Left);

            case TokenType.FN_RIGHT: return(FunctionOperator.Right);

            case TokenType.FN_SUBSTR: return(FunctionOperator.Substring);

            case TokenType.FN_UPPER: return(FunctionOperator.UpperCase);

            case TokenType.FN_LOWER: return(FunctionOperator.LowerCase);

            default:
            {
                throw new NotSupportedException("Token Type " + op.Type + " is not a valid function operator.");
            }
            }
        }
Example #2
0
 public OPathLexer(TextReader reader)
 {
     _lexer          = new OPathBaseLexer(reader);
     _currentToken   = null;
     _lastToken      = null;
     _nextTokenQueue = new Queue();
 }
Example #3
0
 public OPathLexer(TextReader reader)
 {
     _lexer = new OPathBaseLexer(reader);
     _currentToken = null;
     _lastToken = null;
     _nextTokenQueue = new Queue();
 }
Example #4
0
        private int ComparePrecedence(Yytoken left, Yytoken right)
        {
            // compare the group values (not the full group-index value)
            int leftValue  = ((int)left.Type & 0xF00);
            int rightValue = ((int)right.Type & 0xF00);

            int result = -1 * leftValue.CompareTo(rightValue);

#if DEBUG_PARSER
            Debug.WriteLine(string.Format("ComparePrecedence({0}, {1}) = {2}", left.Type, right.Type, result));
#endif
            return(result);
        }
Example #5
0
 public Yytoken Lex()
 {
     _lastToken = _currentToken;
     if( _nextTokenQueue.Count > 0 )
     {
         _currentToken = (Yytoken)_nextTokenQueue.Dequeue();
     }
     else // empty queue
     {
         _currentToken = _lexer.Lex();
     }
     return _currentToken;
 }
Example #6
0
 public Yytoken Lex()
 {
     _lastToken = _currentToken;
     if (_nextTokenQueue.Count > 0)
     {
         _currentToken = (Yytoken)_nextTokenQueue.Dequeue();
     }
     else             // empty queue
     {
         _currentToken = _lexer.Lex();
     }
     return(_currentToken);
 }
Example #7
0
        private UnaryOperator GetUnaryOperator(Yytoken op)
        {
            switch (op.Type)
            {
            case TokenType.NEGATE: return(UnaryOperator.Negation);

            case TokenType.NOT: return(UnaryOperator.LogicalNot);

            case TokenType.FN_ISNULL: return(UnaryOperator.IsNull);

            case TokenType.FN_EXISTS: return(UnaryOperator.Exists);

            default:
            {
                throw new NotSupportedException("Token Type " + op.Type + " is not a valid unary operator.");
            }
            }
        }
Example #8
0
        private BinaryOperator GetBinaryOperator(Yytoken op)
        {
            switch (op.Type)
            {
            case TokenType.OP_EQ: return(BinaryOperator.Equality);

            case TokenType.OP_NE: return(BinaryOperator.Inequality);

            case TokenType.OP_GT: return(BinaryOperator.GreaterThan);

            case TokenType.OP_GE: return(BinaryOperator.GreaterEqual);

            case TokenType.OP_LT: return(BinaryOperator.LessThan);

            case TokenType.OP_LE: return(BinaryOperator.LessEqual);

            case TokenType.AND: return(BinaryOperator.LogicalAnd);

            case TokenType.OR: return(BinaryOperator.LogicalOr);

            case TokenType.PLUS: return(BinaryOperator.Addition);

            case TokenType.MINUS: return(BinaryOperator.Subtraction);

            case TokenType.MULTIPLY: return(BinaryOperator.Multiplication);

            case TokenType.DIVIDE: return(BinaryOperator.Division);

            case TokenType.MODULO: return(BinaryOperator.Modulus);

            default:
            {
                throw new NotSupportedException("Token Type " + op.Type + " is not a valid binary operator.");
            }
            }
        }
Example #9
0
        private void Reduce()
        {
#if DEBUG_PARSER
            DumpStacks("\nReducing...");
#endif
            if (_ops.Count == 0)
            {
                throw new OPathException("Oparators stack is empty. Cannot reduce.");
            }

            Yytoken op = (Yytoken)_ops.Pop();
            switch (op.Type)
            {
            case TokenType.OP_EQ:
            case TokenType.OP_NE:
            case TokenType.OP_GT:
            case TokenType.OP_GE:
            case TokenType.OP_LT:
            case TokenType.OP_LE:
            case TokenType.AND:
            case TokenType.OR:
            case TokenType.PLUS:
            case TokenType.MINUS:
            case TokenType.MULTIPLY:
            case TokenType.DIVIDE:
            case TokenType.MODULO:
            {
                if (_args.Count < 2)
                {
                    throw new OPathException("Not enough arguments on stack for operator " + op.Type + ".");
                }

                BinaryOperator bop   = GetBinaryOperator(op);
                Expression     right = (Expression)_args.Pop();
                Expression     left  = (Expression)_args.Pop();

                _args.Push(new Binary(bop, left, right));
                break;
            }

            case TokenType.FN_TRIM:
            case TokenType.FN_LEN:
            case TokenType.FN_LEFT:
            case TokenType.FN_RIGHT:
            case TokenType.FN_SUBSTR:
            case TokenType.FN_UPPER:
            case TokenType.FN_LOWER:
            {
                if (_args.Count < 1)
                {
                    throw new OPathException("No argument on stack for operator " + op.Type + ".");
                }

                FunctionOperator fop = GetFunctionOperator(op);
                Expression[]     argList;
                if (_args.Peek() is Expression)
                {
                    argList = new Expression[] { (Expression)_args.Pop() };
                }
                else
                {
                    argList = (Expression[])_args.Pop();
                }

                _args.Push(new Function(fop, argList));
                break;
            }

            case TokenType.OP_LIKE:
            case TokenType.OP_IN:
            {
                if (_args.Count < 1)
                {
                    throw new OPathException("No argument on stack for operator " + op.Type + ".");
                }

                FunctionOperator fop = GetFunctionOperator(op);
                Expression[]     argList;
                if (_args.Peek() is Expression)
                {
                    argList    = new Expression[2];
                    argList[1] = (Expression)_args.Pop();
                    argList[0] = (Expression)_args.Pop();
                }
                else
                {
                    Expression[] oldList = (Expression[])_args.Pop();
                    argList = new Expression[oldList.Length + 1];
                    oldList.CopyTo(argList, 1);
                    argList[0] = (Expression)_args.Pop();
                }

                _args.Push(new Function(fop, argList));
                break;
            }

            case TokenType.NEGATE:
            {
                if (_args.Count < 1)
                {
                    throw new OPathException("No argument on stack for operator " + op.Type + ".");
                }

                // try to negate the operand to avoid wrapping it in a unary negation node
                Expression operand = (Expression)_args.Peek();
                if (operand.NodeType == NodeType.Literal)
                {
                    Literal literal = (Literal)operand;

                    object newValue = null;
                    if (literal.Value is int)
                    {
                        newValue = -(int)literal.Value;
                    }
                    else if (literal.Value is decimal)
                    {
                        newValue = -(decimal)literal.Value;
                    }
                    else if (literal.Value is long)
                    {
                        newValue = -(long)literal.Value;
                    }
                    else if (literal.Value is double)
                    {
                        newValue = -(double)literal.Value;
                    }

                    if (newValue != null)
                    {
                        literal.Value = newValue;
                        break;
                    }
                }

                // if we get here, we could not negate the operand
                goto case TokenType.NOT;
            }

            case TokenType.NOT:
            case TokenType.FN_ISNULL:
            case TokenType.FN_EXISTS:
            {
                if (_args.Count < 1)
                {
                    throw new OPathException("No argument on stack for operator " + op.Type + ".");
                }

                UnaryOperator uop     = GetUnaryOperator(op);
                Expression    operand = (Expression)_args.Pop();

                _args.Push(new Unary(uop, operand));
                break;
            }

            case TokenType.PERIOD:
            {
                if (_args.Count < 2)
                {
                    throw new OPathException("Not enough arguments on stack for operator " + op.Type + ".");
                }

                Expression child  = (Expression)_args.Pop();
                Expression parent = (Expression)_args.Pop();

                if (child.NodeType != NodeType.Property && child.NodeType != NodeType.Parent && child.NodeType != NodeType.Axis)
                {
                    throw new OPathException("Invalid expression syntax near character position " + op.Position + ".");
                }

                if (child.NodeType == NodeType.Parent && parent.NodeType != NodeType.Parent)
                {
                    throw new OPathException("Parent relationship operator (^) cannot be applied to a relationship or filter.");
                }

                if (parent.NodeType == NodeType.Property)
                {
                    (parent as Property).IsRelational = true;
                    _args.Push(new Axis(parent, child, true));
                }
                else if (parent.NodeType == NodeType.Parent)
                {
                    if (child.NodeType == NodeType.Axis)
                    {
                        throw new OPathException("Parent relationship operator (^) cannot be applied to a relationship or filter.");
                    }
                    else if (child.NodeType == NodeType.Parent)
                    {
                        (child as Parent).Source = (Parent)parent;
                        _args.Push(child);
                    }
                    else if (child.NodeType == NodeType.Property)
                    {
                        (child as Property).Source = (Parent)parent;
                        _args.Push(child);
                    }
                }
                else if (parent.NodeType == NodeType.Axis)
                {
                    Axis axis = (Axis)parent;
                    if (!axis.IsDot)
                    {
                        _args.Push(new Axis(parent, child, true));
                    }
                    else                             // is dot
                    {
                        // wrap the property at the end of the axis chain into an axis with the child as the new constraint
                        Axis leafAxis = axis;
                        while (leafAxis.Constraint.NodeType == NodeType.Axis)
                        {
                            leafAxis = (Axis)leafAxis.Constraint;
                        }

                        Expression newSource = leafAxis.Constraint;
                        if (newSource.NodeType != NodeType.Property)
                        {
                            throw new OPathException("Constraint on leaf axis is not a Property node.");
                        }

                        (newSource as Property).IsRelational = true;
                        leafAxis.Constraint = new Axis(newSource, child);

                        _args.Push(axis);
                    }
                }
                else
                {
                    throw new OPathException("Parent is not a Property or Axis node.");
                }
                break;
            }

            case TokenType.LBRACE:
            {
                if (_args.Count < 2)
                {
                    throw new OPathException("Not enough arguments on stack for operator " + op.Type + ".");
                }

                Expression constraint = (Expression)_args.Pop();
                Expression source     = (Expression)_args.Pop();

                if (source.NodeType != NodeType.Property)
                {
                    throw new OPathException("Filter source is not a Property node.");
                }

                (source as Property).IsRelational = true;

                _args.Push(new Axis(source, constraint, false));
                break;
            }

            case TokenType.COMMA:
            {
                if (_args.Count < 2)
                {
                    throw new OPathException("Not enough arguments on stack for operator " + op.Type + ".");
                }

                Expression argument = (Expression)_args.Pop();

                Expression[] list;
                if (_args.Peek() is Expression)
                {
                    list    = new Expression[2];
                    list[1] = argument;
                    list[0] = (Expression)_args.Pop();
                }
                else
                {
                    Expression[] oldList = (Expression[])_args.Pop();
                    list = new Expression[oldList.Length + 1];
                    oldList.CopyTo(list, 0);
                    list[list.Length - 1] = argument;
                }

                _args.Push(list);
                break;
            }

            default:
            {
                throw new NotSupportedException("Operator " + op.Type + " is not supported.");
            }
            }

#if DEBUG_PARSER
            DumpStacks("To...");
            Debug.WriteLine("");
#endif
        }
Example #10
0
        private void ProcessToken(Yytoken token, OPathLexer lexer)
        {
            switch (token.Type)
            {
            case TokenType.IDENT:
            {
                Property node = new Property(token.Text, new Context());
                _args.Push(node);
                break;
            }

            case TokenType.PARENT:
            {
                if (lexer.NextToken == null || lexer.NextToken.Type != TokenType.PERIOD)
                {
                    throw new OPathException("Position " + token.Position + ": Parent relationship operator must be followed by a dot operator.");
                }
                Parent node = new Parent(new Context());
                _args.Push(node);
                break;
            }

            case TokenType.PARAM:
            {
                Parameter node = new Parameter(_parameterCount);
                _parameterCount += 1;

                _args.Push(node);
                break;
            }

            case TokenType.CONST:
            {
                Literal node = new Literal(token.Value);
                _args.Push(node);
                break;
            }

            case TokenType.PERIOD:
            {
                Yytoken last = lexer.LastToken;
                Yytoken next = lexer.NextToken;
                if (last == null || next == null)
                {
                    throw new OPathException("Position " + token.Position + ": The dot operator (.) cannot be at the very beginning or end of an expression.");
                }
                // dot operator not valid unless it follows a property/relationship identifier, parent operator, or filter
                if (last.Type != TokenType.IDENT && last.Type != TokenType.PARENT && last.Type != TokenType.RBRACE)
                {
                    throw new OPathException("Position " + token.Position + ": Dot operators cannot be used in this way.");
                }
                // parent operator cannot be after a property/relationship identifer
                if (next.Type == TokenType.PARENT && last.Type != TokenType.PARENT)
                {
                    throw new OPathException("Position " + token.Position + ": Parent relationship operators (^) cannot be used in this way.");
                }
                goto case TokenType.MODULO;
            }

            case TokenType.MINUS:
            {
                // change the token to a negation unless followed by a token that supports subtraction
                Yytoken last = lexer.LastToken;
                if (last == null || (last.Type != TokenType.CONST && last.Type != TokenType.IDENT && last.Type != TokenType.PARAM && last.Type != TokenType.RPAREN))
                {
                    token.Type = TokenType.NEGATE;
                }
                goto case TokenType.COMMA;
            }

            case TokenType.COMMA:
            case TokenType.OP_EQ:
            case TokenType.OP_NE:
            case TokenType.OP_GT:
            case TokenType.OP_GE:
            case TokenType.OP_LT:
            case TokenType.OP_LE:
            case TokenType.OP_LIKE:
            case TokenType.AND:
            case TokenType.OR:
            case TokenType.NOT:
            case TokenType.PLUS:
            case TokenType.MULTIPLY:
            case TokenType.DIVIDE:
            case TokenType.MODULO:
            {
                if (_ops.Count == 0 || ComparePrecedence(token, (Yytoken)_ops.Peek()) > 0)                          // new token has higher precedence
                {
                    _ops.Push(token);
                }
                else                         // new token has lower or same precedence
                {
                    Reduce();
                    // process this token again
                    ProcessToken(token, lexer);                             // note: recursive call
                }
                break;
            }

            case TokenType.OP_IN:
            case TokenType.FN_ISNULL:
            case TokenType.FN_LEN:
            case TokenType.FN_TRIM:
            case TokenType.FN_LEFT:
            case TokenType.FN_RIGHT:
            case TokenType.FN_SUBSTR:
            case TokenType.FN_UPPER:
            case TokenType.FN_LOWER:
            case TokenType.FN_EXISTS:
            {
                Yytoken nextToken = lexer.Lex();
                if (nextToken.Type != TokenType.LPAREN)
                {
                    throw new OPathException("Function '" + token.Text + "' must be followed by an opening parenthesis.");
                }
                _ops.Push(nextToken);
                _ops.Push(token);
                break;
            }

            case TokenType.LPAREN:
            case TokenType.LBRACE:
            {
                _ops.Push(token);
                break;
            }

            case TokenType.RPAREN:
            {
                if (_ops.Count == 0)
                {
                    throw new OPathException("Closing parenthesis encountered without matching opening parenthesis.");
                }

                if (((Yytoken)_ops.Peek()).Type == TokenType.LPAREN)
                {
                    _ops.Pop();                             // "cancel" the operator pair
                }
                else
                {
                    Reduce();
                    // process this token again
                    ProcessToken(token, lexer);                             // note: recursive call
                }
                break;
            }

            case TokenType.RBRACE:
            {
                if (_ops.Count == 0)
                {
                    throw new OPathException("Closing brace encountered without matching opening brace.");
                }

                if (((Yytoken)_ops.Peek()).Type == TokenType.LBRACE)
                {
                    Reduce();                             // a final reduce to "cancel" the pair
                }
                else
                {
                    Reduce();
                    // process this token again
                    ProcessToken(token, lexer);                             // note: recursive call
                }
                break;
            }

            default:
            {
                throw new NotSupportedException("Token type " + token.Type + " at position " + token.Position + " in expression is not supported.");
            }
            }

#if DEBUG_PARSER
            DumpStacks("\nAfter Token: " + token.ToString());
#endif
        }
Example #11
0
        private void ProcessToken(Yytoken token, OPathLexer lexer)
        {
            switch( token.Type )
            {
                case TokenType.IDENT:
                {
                    Property node = new Property(token.Text, new Context());
                    _args.Push(node);
                    break;
                }
                case TokenType.PARENT:
                {
                    if( lexer.NextToken == null || lexer.NextToken.Type != TokenType.PERIOD )
                    {
                        throw new OPathException("Position " + token.Position + ": Parent relationship operator must be followed by a dot operator.");
                    }
                    Parent node = new Parent(new Context());
                    _args.Push(node);
                    break;
                }
                case TokenType.PARAM:
                {
                    Parameter node = new Parameter(_parameterCount);
                    _parameterCount += 1;

                    _args.Push(node);
                    break;
                }
                case TokenType.CONST:
                {
                    Literal node = new Literal(token.Value);
                    _args.Push(node);
                    break;
                }
                case TokenType.PERIOD:
                {
                    Yytoken last = lexer.LastToken;
                    Yytoken next = lexer.NextToken;
                    if( last == null || next == null )
                    {
                        throw new OPathException("Position " + token.Position + ": The dot operator (.) cannot be at the very beginning or end of an expression.");
                    }
                    // dot operator not valid unless it follows a property/relationship identifier, parent operator, or filter
                    if( last.Type != TokenType.IDENT && last.Type != TokenType.PARENT && last.Type != TokenType.RBRACE )
                    {
                        throw new OPathException("Position " + token.Position + ": Dot operators cannot be used in this way.");
                    }
                    // parent operator cannot be after a property/relationship identifer
                    if( next.Type == TokenType.PARENT && last.Type != TokenType.PARENT )
                    {
                        throw new OPathException("Position " + token.Position + ": Parent relationship operators (^) cannot be used in this way.");
                    }
                    goto case TokenType.MODULO;
                }
                case TokenType.MINUS:
                {
                    // change the token to a negation unless followed by a token that supports subtraction
                    Yytoken last = lexer.LastToken;
                    if( last == null || (last.Type != TokenType.CONST && last.Type != TokenType.IDENT && last.Type != TokenType.PARAM && last.Type != TokenType.RPAREN) )
                    {
                        token.Type = TokenType.NEGATE;
                    }
                    goto case TokenType.COMMA;
                }
                case TokenType.COMMA:
                case TokenType.OP_EQ:
                case TokenType.OP_NE:
                case TokenType.OP_GT:
                case TokenType.OP_GE:
                case TokenType.OP_LT:
                case TokenType.OP_LE:
                case TokenType.OP_LIKE:
                case TokenType.AND:
                case TokenType.OR:
                case TokenType.NOT:
                case TokenType.PLUS:
                case TokenType.MULTIPLY:
                case TokenType.DIVIDE:
                case TokenType.MODULO:
                {
                    if( _ops.Count == 0 || ComparePrecedence(token, (Yytoken)_ops.Peek()) > 0 ) // new token has higher precedence
                    {
                        _ops.Push(token);
                    }
                    else // new token has lower or same precedence
                    {
                        Reduce();
                        // process this token again
                        ProcessToken(token, lexer); // note: recursive call
                    }
                    break;
                }
                case TokenType.OP_IN:
                case TokenType.FN_ISNULL:
                case TokenType.FN_LEN:
                case TokenType.FN_TRIM:
                case TokenType.FN_LEFT:
                case TokenType.FN_RIGHT:
                case TokenType.FN_SUBSTR:
                case TokenType.FN_UPPER:
                case TokenType.FN_LOWER:
                case TokenType.FN_EXISTS:
                {
                    Yytoken nextToken = lexer.Lex();
                    if( nextToken.Type != TokenType.LPAREN )
                    {
                        throw new OPathException("Function '" + token.Text + "' must be followed by an opening parenthesis.");
                    }
                    _ops.Push(nextToken);
                    _ops.Push(token);
                    break;
                }
                case TokenType.LPAREN:
                case TokenType.LBRACE:
                {
                    _ops.Push(token);
                    break;
                }
                case TokenType.RPAREN:
                {
                    if( _ops.Count == 0 ) throw new OPathException("Closing parenthesis encountered without matching opening parenthesis.");

                    if( ((Yytoken)_ops.Peek()).Type == TokenType.LPAREN )
                    {
                        _ops.Pop(); // "cancel" the operator pair
                    }
                    else
                    {
                        Reduce();
                        // process this token again
                        ProcessToken(token, lexer); // note: recursive call
                    }
                    break;
                }
                case TokenType.RBRACE:
                {
                    if( _ops.Count == 0 ) throw new OPathException("Closing brace encountered without matching opening brace.");

                    if( ((Yytoken)_ops.Peek()).Type == TokenType.LBRACE )
                    {
                        Reduce(); // a final reduce to "cancel" the pair
                    }
                    else
                    {
                        Reduce();
                        // process this token again
                        ProcessToken(token, lexer); // note: recursive call
                    }
                    break;
                }
                default:
                {
                    throw new NotSupportedException("Token type " + token.Type + " at position " + token.Position + " in expression is not supported.");
                }
            }

            #if DEBUG_PARSER
            DumpStacks("\nAfter Token: " + token.ToString());
            #endif
        }
Example #12
0
 private UnaryOperator GetUnaryOperator(Yytoken op)
 {
     switch( op.Type)
     {
         case TokenType.NEGATE: return UnaryOperator.Negation;
         case TokenType.NOT: return UnaryOperator.LogicalNot;
         case TokenType.FN_ISNULL: return UnaryOperator.IsNull;
         case TokenType.FN_EXISTS: return UnaryOperator.Exists;
         default:
         {
             throw new NotSupportedException("Token Type " + op.Type + " is not a valid unary operator.");
         }
     }
 }
Example #13
0
 private FunctionOperator GetFunctionOperator(Yytoken op)
 {
     switch( op.Type )
     {
         case TokenType.OP_LIKE: return FunctionOperator.Like;
         case TokenType.OP_IN: return FunctionOperator.In;
         case TokenType.FN_TRIM: return FunctionOperator.Trim;
         case TokenType.FN_LEN: return FunctionOperator.Len;
         case TokenType.FN_LEFT: return FunctionOperator.Left;
         case TokenType.FN_RIGHT: return FunctionOperator.Right;
         case TokenType.FN_SUBSTR: return FunctionOperator.Substring;
         case TokenType.FN_UPPER: return FunctionOperator.UpperCase;
         case TokenType.FN_LOWER: return FunctionOperator.LowerCase;
         default:
         {
             throw new NotSupportedException("Token Type " + op.Type + " is not a valid function operator.");
         }
     }
 }
Example #14
0
 private BinaryOperator GetBinaryOperator(Yytoken op)
 {
     switch( op.Type )
     {
         case TokenType.OP_EQ: return BinaryOperator.Equality;
         case TokenType.OP_NE: return BinaryOperator.Inequality;
         case TokenType.OP_GT: return BinaryOperator.GreaterThan;
         case TokenType.OP_GE: return BinaryOperator.GreaterEqual;
         case TokenType.OP_LT: return BinaryOperator.LessThan;
         case TokenType.OP_LE: return BinaryOperator.LessEqual;
         case TokenType.AND: return BinaryOperator.LogicalAnd;
         case TokenType.OR: return BinaryOperator.LogicalOr;
         case TokenType.PLUS: return BinaryOperator.Addition;
         case TokenType.MINUS: return BinaryOperator.Subtraction;
         case TokenType.MULTIPLY: return BinaryOperator.Multiplication;
         case TokenType.DIVIDE: return BinaryOperator.Division;
         case TokenType.MODULO: return BinaryOperator.Modulus;
         default:
         {
             throw new NotSupportedException("Token Type " + op.Type + " is not a valid binary operator.");
         }
     }
 }
Example #15
0
        private int ComparePrecedence(Yytoken left, Yytoken right)
        {
            // compare the group values (not the full group-index value)
            int leftValue = ((int)left.Type & 0xF00);
            int rightValue = ((int)right.Type & 0xF00);

            int result = -1 * leftValue.CompareTo(rightValue);

            #if DEBUG_PARSER
            Debug.WriteLine(string.Format("ComparePrecedence({0}, {1}) = {2}", left.Type, right.Type, result));
            #endif
            return result;
        }
Example #16
0
        private OrderByItem ParseItem(OPathLexer lexer, EntityMap entity, OrderByJoinCollection joins, OrderByJoin parentJoin)
        {
            Yytoken token = lexer.CurrentToken;

            if (token.Type != TokenType.IDENT)
            {
                throw new OPathException("'" + token.Text + "' encountered where a property or relationship was expected in sort expression '" + _expression + "'.");
            }

            string propertyName = token.Text;

            token = lexer.Lex();
            if (token == null)
            {
                FieldMap field;
                try
                {
                    field = entity.GetFieldMap(propertyName);
                }
                catch
                {
                    throw new OPathException(string.Format("The specified property '{0}' in the sort '{1}' is not defined in the entity map for type '{2}'.", propertyName, _expression, entity.Type));
                }

                return(new OrderByItem(propertyName, field, true, parentJoin));
            }
            if (token.Type != TokenType.PERIOD)
            {
                if (token.Type != TokenType.ASCEND && token.Type != TokenType.DESCEND && token.Type != TokenType.COMMA)
                {
                    throw new OPathException("'" + token.Text + "' is not valid in sort expression '" + _expression + "'.");
                }

                FieldMap field;
                try
                {
                    field = entity.GetFieldMap(propertyName);
                }
                catch
                {
                    throw new OPathException(string.Format("The specified property '{0}' in the sort '{1}' is not defined in the entity map for type '{2}'.", propertyName, _expression, entity.Type));
                }

                bool ascending = (token.Type != TokenType.DESCEND);

                if (token.Type != TokenType.COMMA)
                {
                    lexer.MoveToNext();
                }
                lexer.MoveToNext();

                return(new OrderByItem(propertyName, field, ascending, parentJoin));
            }
            else             // dot operator (.)
            {
                token = lexer.Lex();
                if (token == null)
                {
                    throw new OPathException("End of expression encountered where a property or relationship was expected in sort expression '" + _expression + "'.");
                }
                if (token.Type != TokenType.IDENT)
                {
                    throw new OPathException("'" + token.Text + "' encountered where a property or relationship was expected in sort expression '" + _expression + "'.");
                }

                RelationMap relation = entity.Relation(propertyName);
                if (relation == null)
                {
                    throw new OPathException(string.Format("The specified relationship '{0}' in the sort expression '{1}' is not defined in the entity map for type '{2}'.", propertyName, _expression, entity.Type));
                }
                if (relation.Relationship != Relationship.Parent)
                {
                    throw new Exception("Relationship '" + relation.Alias + "' is not a ManyToOne relation.  Only ManyToOne relations are allowed in sort expressions.");
                }

                EntityMap relEntity = _maps[relation.Type];

                OrderByJoin join = joins[propertyName];
                if (join == null)
                {
                    join = new OrderByJoin(relation);
                    joins.Add(join);
                }

                // recursive call
                return(ParseItem(lexer, relEntity, join.NestedJoins, join));
            }
        }
Example #17
0
        public Yytoken Lex()
        {
            char yy_lookahead;
            int  yy_anchor            = YY_NO_ANCHOR;
            int  yy_state             = yy_state_dtrans[yy_lexical_state];
            int  yy_next_state        = YY_NO_STATE;
            int  yy_last_accept_state = YY_NO_STATE;
            bool yy_initial           = true;
            int  yy_this_accept;

            yy_mark_start();
            yy_this_accept = yy_acpt[yy_state];
            if (YY_NOT_ACCEPT != yy_this_accept)
            {
                yy_last_accept_state = yy_state;
                yy_mark_end();
            }
            while (true)
            {
                if (yy_initial && yy_at_bol)
                {
                    yy_lookahead = (char)YY_BOL;
                }
                else
                {
                    yy_lookahead = yy_advance();
                }
                yy_next_state = yy_nxt[yy_rmap[yy_state], yy_cmap[yy_lookahead]];
                if (YY_EOF == yy_lookahead && yy_initial)
                {
                    yy_do_eof();
                    return(null);
                }
                if (YY_F != yy_next_state)
                {
                    yy_state       = yy_next_state;
                    yy_initial     = false;
                    yy_this_accept = yy_acpt[yy_state];
                    if (YY_NOT_ACCEPT != yy_this_accept)
                    {
                        yy_last_accept_state = yy_state;
                        yy_mark_end();
                    }
                }
                else
                {
                    if (YY_NO_STATE == yy_last_accept_state)
                    {
                        throw new System.ApplicationException("Lexical Error: Unmatched Input.");
                    }
                    else
                    {
                        yy_anchor = yy_acpt[yy_last_accept_state];
                        if (0 != (YY_END & yy_anchor))
                        {
                            yy_move_end();
                        }
                        yy_to_mark();
                        if (yy_last_accept_state < 0)
                        {
                            if (yy_last_accept_state < 48)
                            {
                                yy_error(YY_E_INTERNAL, false);
                            }
                        }
                        else
                        {
                            AcceptMethod m = accept_dispatch[yy_last_accept_state];
                            if (m != null)
                            {
                                Yytoken tmp = m();
                                if (tmp != null)
                                {
                                    return(tmp);
                                }
                            }
                        }
                        yy_initial           = true;
                        yy_state             = yy_state_dtrans[yy_lexical_state];
                        yy_next_state        = YY_NO_STATE;
                        yy_last_accept_state = YY_NO_STATE;
                        yy_mark_start();
                        yy_this_accept = yy_acpt[yy_state];
                        if (YY_NOT_ACCEPT != yy_this_accept)
                        {
                            yy_last_accept_state = yy_state;
                            yy_mark_end();
                        }
                    }
                }
            }
        }