/// <summary> /// Performs cube syntactical analysis over collection of <see cref="Token"/> objects using <see cref="IStatedTwoWayEnumerator{T}"/>. /// </summary> /// <param name="enumerator">Extended enumerator of collection of <see cref="Token"/> objects.</param> /// <param name="expression">Output parsed cube if syntactic analysis was succeeded.</param> /// <returns><value>True</value> if succeeded. <value>False</value> if failed.</returns> internal static bool TryParseCube(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; var cube = Mdx.Cube(); do { if (!IsNextTokenValid(enumerator, TokenType.IdentifierExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } string cubeTitleWithBrackets = enumerator.Current.Value; string cubeTitle = cubeTitleWithBrackets.Substring(1, cubeTitleWithBrackets.Length - 2); cube.Titled(cubeTitle); } while (IsNextTokenValid(enumerator, TokenType.IdentifierSeparator)); expression = cube; enumerator.RemoveLastSavedState(); return(true); }
/// <summary> /// Appends the specified <see cref="MdxSet"/> and returns the updated current instance of <see cref="MdxTuple"/>. /// If there are any children other than <see cref="MdxSet"/> then each child will be wrapped into <see cref="MdxSet"/>. /// </summary> /// <param name="set">Specified <see cref="MdxSet"/>.</param> /// <returns>Returns the updated current instance of <see cref="MdxTuple"/>.</returns> public MdxTuple With(MdxSet set) { if (!_children.Any()) { _children.Add(set); return(this); } if (_children.OfType <MdxSet>().Any()) { _children.Add(set); return(this); } var copiedChildren = new List <IMdxMember>(_children); _children.Clear(); foreach (var member in copiedChildren) { _children.Add(Mdx.Set().With(member)); } return(this); }
/// <summary> /// Performs constant value syntactical analysis over collection of <see cref="Token"/> objects using <see cref="IStatedTwoWayEnumerator{T}"/>. /// </summary> /// <param name="enumerator">Extended enumerator of collection of <see cref="Token"/> objects.</param> /// <param name="expression">Output parsed constant value if syntactic analysis was succeeded.</param> /// <returns><value>True</value> if succeeded. <value>False</value> if failed.</returns> internal static bool TryParseConstantValue(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; var constantValue = Mdx.ConstantValue(); if (!IsNextTokenValid(enumerator, TokenType.LogicalExpression) && !IsNextTokenValid(enumerator, TokenType.DateExpression) && !IsNextTokenValid(enumerator, TokenType.TitleExpression) && !IsNextTokenValid(enumerator, TokenType.NumberExpression) && !IsNextTokenValid(enumerator, TokenType.AnyExpression) && !IsNextTokenValid(enumerator, TokenType.Ordering)) { enumerator.RestoreLastSavedPosition(); return(false); } string constantVal = enumerator.Current.Value; if (IsNextTokenValid(enumerator, TokenType.AnyExpression)) { constantVal += enumerator.Current.Value; } constantValue.WithValue(constantVal); expression = constantValue; enumerator.RemoveLastSavedState(); return(true); }
/// <summary> /// Performs navigation function syntactical analysis over collection of <see cref="Token"/> objects using <see cref="IStatedTwoWayEnumerator{T}"/>. /// </summary> /// <param name="enumerator">Extended enumerator of collection of <see cref="Token"/> objects.</param> /// <param name="expression">Output parsed navigation function if syntactic analysis was succeeded.</param> /// <returns><value>True</value> if succeeded. <value>False</value> if failed.</returns> internal static bool TryParseNavigationFunction(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; var navigationFunction = Mdx.NavigationFunction(); if (!IsNextTokenValid(enumerator, TokenType.TitleExpression) && !IsNextTokenValid(enumerator, TokenType.DimensionProperty)) { enumerator.RestoreLastSavedPosition(); return(false); } navigationFunction.Titled(enumerator.Current.Value); if (!IsNextTokenValid(enumerator, TokenType.LeftRoundBracket)) { expression = navigationFunction; enumerator.RemoveLastSavedState(); return(true); } do { if (!IsNextTokenValid(enumerator, TokenType.LogicalExpression) && !IsNextTokenValid(enumerator, TokenType.DateExpression) && !IsNextTokenValid(enumerator, TokenType.NumberExpression) && !IsNextTokenValid(enumerator, TokenType.AnyExpression) && !IsNextTokenValid(enumerator, TokenType.MathsOperator)) { enumerator.RestoreLastSavedPosition(); return(false); } var functionParametersValue = enumerator.Current.Value; if (IsNextTokenValid(enumerator, TokenType.AnyExpression)) { functionParametersValue += enumerator.Current.Value; } navigationFunction.WithParameters(functionParametersValue); } while (IsNextTokenValid(enumerator, TokenType.MemberSeparator)); if (!IsNextTokenValid(enumerator, TokenType.RightRoundBracket)) { enumerator.RestoreLastSavedPosition(); return(false); } expression = navigationFunction; enumerator.RemoveLastSavedState(); return(true); }
/// <summary> /// Performs function syntactical analysis over collection of <see cref="Token"/> objects using <see cref="IStatedTwoWayEnumerator{T}"/>. /// </summary> /// <param name="enumerator">Extended enumerator of collection of <see cref="Token"/> objects.</param> /// <param name="expression">Output parsed function if syntactic analysis was succeeded.</param> /// <returns><value>True</value> if succeeded. <value>False</value> if failed.</returns> internal static bool TryParseFunction(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; var function = Mdx.Function(); do { if (!IsNextTokenValid(enumerator, TokenType.TitleExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } function.Titled(enumerator.Current.Value); } while (IsNextTokenValid(enumerator, TokenType.IdentifierSeparator)); if (!IsNextTokenValid(enumerator, TokenType.LeftRoundBracket)) { enumerator.RestoreLastSavedPosition(); return(false); } if (IsNextTokenValid(enumerator, TokenType.RightRoundBracket)) { expression = function; enumerator.RemoveLastSavedState(); return(true); } do { MdxExpressionBase childExpression; if (!TryParseExpression(enumerator, out childExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } function.WithParameters((MdxExpression)childExpression); } while (IsNextTokenValid(enumerator, TokenType.MemberSeparator)); if (!IsNextTokenValid(enumerator, TokenType.RightRoundBracket)) { enumerator.RestoreLastSavedPosition(); return(false); } expression = function; enumerator.RemoveLastSavedState(); return(true); }
internal static bool TryParseWithDeclaration(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; var declaration = Mdx.Declaration(); if (!IsNextTokenValid(enumerator, TokenType.Member) && !IsNextTokenValid(enumerator, TokenType.Set)) { enumerator.RestoreLastSavedPosition(); return(false); } do { if (!IsNextTokenValid(enumerator, TokenType.IdentifierExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } string identifierWithBrackets = enumerator.Current.Value; string identifierTitle = identifierWithBrackets.Substring(1, identifierWithBrackets.Length - 2); declaration.Titled(identifierTitle); } while (IsNextTokenValid(enumerator, TokenType.IdentifierSeparator)); if (!IsNextTokenValid(enumerator, TokenType.As)) { enumerator.RestoreLastSavedPosition(); return(false); } MdxExpressionBase declarationExpression; if (TryParseTuple(enumerator, out declarationExpression)) { declaration.As((MdxTuple)declarationExpression); } else if (TryParseExpression(enumerator, out declarationExpression)) { declaration.As((MdxExpression)declarationExpression); } else { enumerator.RestoreLastSavedPosition(); return(false); } expression = declaration; enumerator.RemoveLastSavedState(); return(true); }
/// <summary> /// Appends the specified <see cref="MdxTuple"/>, but wraps it into <see cref="MdxSet"/> and returns the updated /// current instance of <see cref="MdxTuple"/>. If there are any <see cref="MdxSet"/>s in <see cref="Children"/> /// then specified <see cref="MdxTuple"/> is appended to the last <see cref="MdxSet"/>. /// </summary> /// <param name="tuple">Specified <see cref="MdxTuple"/>.</param> /// <returns>Returns the updated current instance of <see cref="MdxTuple"/>.</returns> public MdxTuple With(MdxTuple tuple) { var lastSet = _children.OfType <MdxSet>().LastOrDefault(); if (lastSet == null) { return(With(Mdx.Set().With(tuple))); } lastSet.With(tuple); return(this); }
/// <summary> /// Appends the specified <see cref="MdxSet"/>, but wraps it into <see cref="MdxTuple"/> and returns the updated /// current instance of <see cref="MdxSet"/>. If there are any <see cref="MdxTuple"/>s in <see cref="Children"/> /// then specified <see cref="MdxSet"/> is appended to the last <see cref="MdxTuple"/>. /// </summary> /// <param name="set">Specified <see cref="MdxSet"/>.</param> /// <returns>Returns the updated current instance of <see cref="MdxSet"/>.</returns> public MdxSet With(MdxSet set) { var lastTuple = _children.OfType <MdxTuple>().LastOrDefault(); if (lastTuple == null) { With(Mdx.Tuple().With(set)); return(this); } lastTuple.With(set); return(this); }
/// <summary> /// Performs expression syntactical analysis over collection of <see cref="Token"/> objects using <see cref="IStatedTwoWayEnumerator{T}"/>. /// </summary> /// <param name="enumerator">Extended enumerator of collection of <see cref="Token"/> objects.</param> /// <param name="expression">Output parsed expression if syntactic analysis was succeeded.</param> /// <returns><value>True</value> if succeeded. <value>False</value> if failed.</returns> internal static bool TryParseExpression(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; var mdxExpression = Mdx.Expression(); //TODO: Think how to apply NOT and - do { MdxExpressionBase childExpression; if (TryParseFunction(enumerator, out childExpression)) { mdxExpression.WithOperand((MdxFunction)childExpression); } else if (TryParseTuple(enumerator, out childExpression)) { mdxExpression.WithOperand((MdxTuple)childExpression); } else if (TryParseSet(enumerator, out childExpression)) { mdxExpression.WithOperand((MdxSet)childExpression); } else if (TryParseRange(enumerator, out childExpression)) { mdxExpression.WithOperand((MdxRange)childExpression); } else if (TryParseMember(enumerator, out childExpression)) { mdxExpression.WithOperand((MdxMember)childExpression); } else if (TryParseConstantValue(enumerator, out childExpression)) { mdxExpression.WithOperand((MdxConstantExpression)childExpression); } else if (IsNextTokenValid(enumerator, TokenType.NotOperator)) { if (!TryParseExpression(enumerator, out childExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } mdxExpression.WithOperand(((MdxExpression)childExpression).AsNegated()); } else if (IsNextTokenValid(enumerator, TokenType.LeftRoundBracket)) { if (!TryParseExpression(enumerator, out childExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } mdxExpression.WithOperand((MdxExpression)childExpression); if (!IsNextTokenValid(enumerator, TokenType.RightRoundBracket)) { enumerator.RestoreLastSavedPosition(); return(false); } } else { enumerator.RestoreLastSavedPosition(); return(false); } if (!IsNextTokenValid(enumerator, TokenType.MathsOperator) && !IsNextTokenValid(enumerator, TokenType.LogicsOperator)) { break; } mdxExpression.WithOperator(enumerator.Current.Value); } while (true); expression = mdxExpression; enumerator.RemoveLastSavedState(); return(true); }
/// <summary> /// Performs axis syntactical analysis over collection of <see cref="Token"/> objects using <see cref="IStatedTwoWayEnumerator{T}"/>. /// </summary> /// <param name="enumerator">Extended enumerator of collection of <see cref="Token"/> objects.</param> /// <param name="expression">Output parsed axis if syntactic analysis was succeeded.</param> /// <returns><value>True</value> if succeeded. <value>False</value> if failed.</returns> internal static bool TryParseAxis(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; var axis = Mdx.Axis(); if (IsNextTokenValid(enumerator, TokenType.Non)) { if (!IsNextTokenValid(enumerator, TokenType.Empty)) { enumerator.RestoreLastSavedPosition(); return(false); } axis.AsNonEmpty(); } MdxExpressionBase slicer; if (TryParseTuple(enumerator, out slicer)) { axis.WithSlicer((MdxTuple)slicer); } else if (TryParseSet(enumerator, out slicer)) { axis.WithSlicer(Mdx.Tuple().With((MdxSet)slicer)); } else if (TryParseRange(enumerator, out slicer)) { axis.WithSlicer(Mdx.Tuple().With((MdxRange)slicer)); } else if (TryParseMember(enumerator, out slicer)) { axis.WithSlicer(Mdx.Tuple().With((MdxMember)slicer)); } else if (TryParseFunction(enumerator, out slicer)) { axis.WithSlicer(Mdx.Tuple().With((MdxFunction)slicer)); } else { enumerator.RestoreLastSavedPosition(); return(false); } if (IsNextTokenValid(enumerator, TokenType.Dimension)) { if (!IsNextTokenValid(enumerator, TokenType.Properties)) { enumerator.RestoreLastSavedPosition(); return(false); } do { if (!IsNextTokenValid(enumerator, TokenType.DimensionProperty)) { enumerator.RestoreLastSavedPosition(); return(false); } axis.WithProperties(enumerator.Current.Value); } while (IsNextTokenValid(enumerator, TokenType.MemberSeparator)); } else if (IsNextTokenValid(enumerator, TokenType.Properties)) { do { if (!IsNextTokenValid(enumerator, TokenType.DimensionProperty)) { enumerator.RestoreLastSavedPosition(); return(false); } axis.WithProperties(enumerator.Current.Value); } while (IsNextTokenValid(enumerator, TokenType.MemberSeparator)); } if (!IsNextTokenValid(enumerator, TokenType.On)) { enumerator.RestoreLastSavedPosition(); return(false); } if (!IsNextTokenValid(enumerator, TokenType.AxisNameIdentifier) && !IsNextTokenValid(enumerator, TokenType.NumberExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } string axisName = enumerator.Current.Value; axis.Titled(axisName); expression = axis; enumerator.RemoveLastSavedState(); return(true); }
/// <summary> /// Performs member syntactical analysis over collection of <see cref="Token"/> objects using <see cref="IStatedTwoWayEnumerator{T}"/>. /// </summary> /// <param name="enumerator">Extended enumerator of collection of <see cref="Token"/> objects.</param> /// <param name="expression">Output parsed member if syntactic analysis was succeeded.</param> /// <returns><value>True</value> if succeeded. <value>False</value> if failed.</returns> internal static bool TryParseMember(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; var member = Mdx.Member(); if (!IsNextTokenValid(enumerator, TokenType.IdentifierExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } string identifierWithBrackets = enumerator.Current.Value; string identifierTitle = identifierWithBrackets.Substring(1, identifierWithBrackets.Length - 2); member.Titled(identifierTitle); while (IsNextTokenValid(enumerator, TokenType.IdentifierSeparator)) { MdxExpressionBase function; if (TryParseNavigationFunction(enumerator, out function)) { member.WithFunction((MdxNavigationFunction)function); continue; } if (!IsNextTokenValid(enumerator, TokenType.IdentifierExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } identifierWithBrackets = enumerator.Current.Value; identifierTitle = identifierWithBrackets.Substring(1, identifierWithBrackets.Length - 2); member.Titled(identifierTitle); } if (!IsNextTokenValid(enumerator, TokenType.ValueSeparator)) { expression = member; enumerator.RemoveLastSavedState(); return(true); } if (!IsNextTokenValid(enumerator, TokenType.IdentifierExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } string valueWithBrackets = enumerator.Current.Value; string value = valueWithBrackets.Substring(1, valueWithBrackets.Length - 2); member.WithValue(value); while (IsNextTokenValid(enumerator, TokenType.IdentifierSeparator)) { MdxExpressionBase function; if (!TryParseNavigationFunction(enumerator, out function)) { enumerator.RestoreLastSavedPosition(); return(false); } member.WithFunction((MdxNavigationFunction)function); } expression = member; enumerator.RemoveLastSavedState(); return(true); }
/// <summary> /// Performs set syntactical analysis over collection of <see cref="Token"/> objects using <see cref="IStatedTwoWayEnumerator{T}"/>. /// </summary> /// <param name="enumerator">Extended enumerator of collection of <see cref="Token"/> objects.</param> /// <param name="expression">Output parsed set if syntactic analysis was succeeded.</param> /// <returns><value>True</value> if succeeded. <value>False</value> if failed.</returns> internal static bool TryParseSet(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; if (!IsNextTokenValid(enumerator, TokenType.LeftRoundBracket)) { enumerator.RestoreLastSavedPosition(); return(false); } var set = Mdx.Set(); if (IsNextTokenValid(enumerator, TokenType.RightRoundBracket)) { expression = set; enumerator.RemoveLastSavedState(); return(true); } do { MdxExpressionBase childExpression; if (TryParseRange(enumerator, out childExpression)) { set.With((MdxRange)childExpression); } else if (TryParseMember(enumerator, out childExpression)) { set.With((MdxMember)childExpression); } else if (TryParseTuple(enumerator, out childExpression)) { set.With((MdxTuple)childExpression); } else if (TryParseSet(enumerator, out childExpression)) { set.With((MdxSet)childExpression); } else if (TryParseFunction(enumerator, out childExpression)) { set.With((MdxFunction)childExpression); } else { enumerator.RestoreLastSavedPosition(); return(false); } } while (IsNextTokenValid(enumerator, TokenType.MemberSeparator)); if (!IsNextTokenValid(enumerator, TokenType.RightRoundBracket)) { enumerator.RestoreLastSavedPosition(); return(false); } expression = set; enumerator.RemoveLastSavedState(); return(true); }
/// <summary> /// Performs query syntactical analysis over collection of <see cref="Token"/> objects using <see cref="IStatedTwoWayEnumerator{T}"/>. /// </summary> /// <param name="enumerator">Extended enumerator of collection of <see cref="Token"/> objects.</param> /// <param name="expression">Output parsed query if syntactic analysis was succeeded.</param> /// <returns><value>True</value> if succeeded. <value>False</value> if failed.</returns> internal static bool TryParseQuery(IStatedTwoWayEnumerator <Token> enumerator, out MdxExpressionBase expression) { enumerator.SavePosition(); expression = null; var query = Mdx.Query(); if (IsNextTokenValid(enumerator, TokenType.With)) { MdxExpressionBase declaration; if (!TryParseWithDeclaration(enumerator, out declaration)) { enumerator.RestoreLastSavedPosition(); return(false); } query.With((MdxDeclaration)declaration); while (TryParseWithDeclaration(enumerator, out declaration)) { query.With((MdxDeclaration)declaration); } } if (!IsNextTokenValid(enumerator, TokenType.Select)) { enumerator.RestoreLastSavedPosition(); return(false); } do { MdxExpressionBase childExpression; if (!TryParseAxis(enumerator, out childExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } query.On((MdxAxis)childExpression); } while (IsNextTokenValid(enumerator, TokenType.MemberSeparator)); if (!IsNextTokenValid(enumerator, TokenType.From)) { enumerator.RestoreLastSavedPosition(); return(false); } if (IsNextTokenValid(enumerator, TokenType.LeftRoundBracket)) { MdxExpressionBase innerQuery; if (!TryParseQuery(enumerator, out innerQuery)) { enumerator.RestoreLastSavedPosition(); return(false); } query.From((MdxQuery)innerQuery); if (!IsNextTokenValid(enumerator, TokenType.RightRoundBracket)) { enumerator.RestoreLastSavedPosition(); return(false); } } else { do { MdxExpressionBase childExpression; if (!TryParseCube(enumerator, out childExpression)) { enumerator.RestoreLastSavedPosition(); return(false); } query.From((MdxCube)childExpression); } while (IsNextTokenValid(enumerator, TokenType.MemberSeparator)); } if (!IsNextTokenValid(enumerator, TokenType.Where)) { expression = query; enumerator.RemoveLastSavedState(); return(true); } MdxExpressionBase slicer; if (TryParseRange(enumerator, out slicer)) { query.Where(Mdx.Tuple().With((MdxRange)slicer)); } else if (TryParseMember(enumerator, out slicer)) { query.Where(Mdx.Tuple().With((MdxMember)slicer)); } else if (TryParseSet(enumerator, out slicer)) { query.Where(Mdx.Tuple().With((MdxSet)slicer)); } else if (TryParseTuple(enumerator, out slicer)) { query.Where((MdxTuple)slicer); } else if (TryParseFunction(enumerator, out slicer)) { query.Where((MdxTuple)slicer); } else { enumerator.RestoreLastSavedPosition(); return(false); } expression = query; enumerator.RemoveLastSavedState(); return(true); }