/// <summary> /// Parser /// </summary> /// <returns>An AST</returns> public Query Parse() { Where where = null; OrderBy orderBy = null; GroupBy groupBy = null; _token = _scanner.GetToken(); if (_token.Ttype == TokenType.WHERE) { where = WhereRule(); } if (_token.Ttype == TokenType.ORDERBY) { orderBy = OrderByRule(); } if (_token.Ttype == TokenType.GROUPBY) { groupBy = GroupByRule(); } Sequence sequence = _astFactory.CreateSequence(where, _astFactory.CreateSequence(orderBy, _astFactory.CreateSequence(groupBy, null))); Query expression = _astFactory.CreateQuery(sequence); return expression; }
/// <summary> /// Gets the token. /// </summary> /// <returns>The token Type</returns> /// <exception cref="ScannerException"><c>LexerException</c>.</exception> public override Token GetToken() { SaveScannerState(); EatSpaces(); if (EndOfLine()) { return new Token(TokenType.EOL); } MarkStartOfToken(); if (char.IsLetter(CurrentChar)) { _token = ScanReservedWordOrSymbol(); } else if (Char.IsDigit(CurrentChar)) { _token = ScanNumber(); } else if (CurrentChar == '[') { _token = ScanBracketSymbol(); } else if (CurrentChar == '"') { _token = ScanString(); } else if (CurrentChar == '#') { _token = ScanDate(); } else if (STOP_CHARS.IndexOf(CurrentChar) != -1 && !_inQuotes) { _token = ScanOperator(); } if (_token == null) { throw new ScannerException( string.Format(CultureInfo.CurrentCulture, "Unknow character at {0}", CurrentPosition)); } SetScannerStateToken(_token); return _token; }
private Operation IsNullOrNotIsNullRule(FieldNode field) { _token = _scanner.GetToken(); switch (_token.Ttype) { case TokenType.NULL: return _astFactory.CreateComparationIsNull(field); case TokenType.NOT: _token = _scanner.GetToken(); if (_token.Ttype == TokenType.NULL) { return _astFactory.CreateComparationIsNotNull(field); } throw new ParserException( string.Format(CultureInfo.InvariantCulture, "Missing NULL at {0}", _scanner.CurrentPosition)); default: throw new ParserException( string.Format(CultureInfo.InvariantCulture, "Missing NULL at {0}", _scanner.CurrentPosition)); } }
/// <summary> /// VALUE expression Rule /// </summary> /// <returns></returns> /// <exception cref="ParserException"><c>ParserException</c>.</exception> private ValueNode ValueRule() { _token = _scanner.GetToken(); if (_token.Ttype == TokenType.VALUE) { return _astFactory.CreateValueNode(_token.Value, _token.ValueType.ToString()); } if (_token.Ttype == TokenType.NULL) { return null; } throw new ParserException( string.Format(CultureInfo.InvariantCulture, "TokenValue expected at {0}", _scanner.CurrentPosition)); }
/// <summary> /// FIELD expression Rule /// </summary> /// <returns></returns> /// <exception cref="ParserException"><c>ParserException</c>.</exception> private FieldNode FieldRule() { _token = _scanner.GetToken(); if (_token.Ttype == TokenType.FIELD) { FieldNode fieldNode = _astFactory.CreateFieldNode(_token.Value); return fieldNode; } throw new ParserException( string.Format(CultureInfo.InvariantCulture, "Field name expected at {0}", _scanner.CurrentPosition)); }
/// <summary> /// FIELDLISTORDER /// | FieldNodeOrder /// | FieldNodeOrder, FIELDLISTORDER /// </summary> /// <returns>AST FieldList Tree</returns> private FieldList FieldsListOrderRule() { FieldNode fieldNodeWithOrder = FieldNodeOrderRule(); _token = _scanner.GetToken(); if (_token.Ttype == TokenType.COMMA) { return _astFactory.CreateFieldList(fieldNodeWithOrder, FieldsListOrderRule()); } return _astFactory.CreateFieldList(fieldNodeWithOrder); }
/// <summary> /// FIELDNODEORDER /// | FieldNode DESC /// | FieldNode ASC /// | FieldNode /// </summary> /// <returns>AST FieldNode</returns> private FieldNode FieldNodeOrderRule() { FieldNode fieldNode = FieldRule(); _token = _scanner.GetToken(); switch (_token.Ttype) { case TokenType.DESC: fieldNode.Ascending = false; return fieldNode; case TokenType.ASC: fieldNode.Ascending = true; return fieldNode; default: _scanner.BackToken(); break; } return fieldNode; }
/// <summary> /// FIELDLIST /// | FieldNode /// | FieldNode, FIELDLIST /// </summary> /// <returns>AST FieldList Tree</returns> private FieldList FieldListRule() { FieldNode fieldNode = FieldRule(); _token = _scanner.GetToken(); if (_token.Ttype == TokenType.COMMA) { return _astFactory.CreateFieldList(fieldNode, FieldListRule()); } return _astFactory.CreateFieldList(fieldNode); }
/// <summary> /// COMPARATION Expression Rule /// | FieldRule COMPARATOR ValueRule /// </summary> /// <returns>AST Operation Tree</returns> /// <exception cref="ParserException"><c>ParserException</c>.</exception> private Operation ComparationRule(FieldNode field) { _token = _scanner.GetToken(); switch (_token.Ttype) { case TokenType.LESS: return _astFactory.CreateComparationLess(field, ValueRule()); case TokenType.GREATER: return _astFactory.CreateComparationGreater(field, ValueRule()); case TokenType.LESS_EQ: return _astFactory.CreateComparationLessEqual(field, ValueRule()); case TokenType.GREATER_EQ: return _astFactory.CreateComparationGraterEqual(field, ValueRule()); case TokenType.EQ: return IsNullOrEqualRule(field); case TokenType.NOT_EQ: return IsNotNullOrNotEqualRule(field); case TokenType.IS: return IsNullOrNotIsNullRule(field); case TokenType.LIKE: return _astFactory.CreateComparationContains(field, ValueRule()); case TokenType.BEGINS: return _astFactory.CreateComparationBegin(field, ValueRule()); default: throw new ParserException( string.Format(CultureInfo.InvariantCulture, "Invalid Operation at {0}", _scanner.CurrentPosition)); } }
/// <summary> /// BOOLEAN expression Rule /// | '(' BooleanRule ')' /// | OperationRule /// <returns></returns> private Expression BooleanRule() { _token = _scanner.GetToken(); switch (_token.Ttype) { case TokenType.LEFT_PARENTHESIS: _parenthesisDepth++; return BooleanOperatorRule(); case TokenType.FIELD: FieldNode fieldNode = _astFactory.CreateFieldNode(_token.Value); return _astFactory.CreateExpression(ComparationRule(fieldNode)); default: throw new ParserException("Field expected."); } }
/// <summary> /// BOOLEAN Operation expression Rule /// | BooleanRule /// | BooleanRule AND BooleanOperatorRule /// | BooleanRule OR BooleanOperatorRule /// <returns></returns> private Expression BooleanOperatorRule() { Expression booleanExp = BooleanRule(); _token = _scanner.GetToken(); switch (_token.Ttype) { case TokenType.AND: return _astFactory.CreateBooleanAnd(booleanExp, BooleanOperatorRule()); case TokenType.OR: return _astFactory.CreateBooleanOr(booleanExp, BooleanOperatorRule()); case TokenType.RIGHT_PARENTHESIS: _parenthesisDepth--; break; } return booleanExp; }