/// <summary> /// Accepts the source context (by <see cref="IParsingContextStream.Accept"/>) and returns accepted fragment (<see cref="IParsingContextStream.GetAcceptedFragmentOrEmpty"/>). /// <seealso cref="IParsingContextStream.Accept"/> /// <seealso cref="IParsingContextStream.GetAcceptedFragmentOrEmpty"/> /// <seealso cref="GetAcceptedFragment"/> /// <seealso cref="TryGetAcceptedFragment"/> /// </summary> /// <param name="source">The source.</param> /// <returns>The accepted fragment.</returns> public static ISourceCodeFragment AcceptAndGetFragment(this IParsingContextStream source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } source.Accept(); return(source.GetAcceptedFragmentOrEmpty()); }
public static bool ParseOneOf(this IParsingContextStream source, ISet <char> charSet, bool accept = false, IEqualityComparer <char> charComparer = null) { if (source.HasNext && source.Next.IsContainedBy(charSet, charComparer)) { source.MoveNext(); if (accept) { source.Accept(); } return(true); } return(false); }
public static bool ParseWhen(this IParsingContextStream source, Func <char, bool> predicate, bool accept = false) { if (source.HasNext && predicate.Invoke(source.Next)) { source.MoveNext(); if (accept) { source.Accept(); } return(true); } return(false); }
public static bool ParseChar(this IParsingContextStream source, char ch1, char ch2, bool accept = false) { if (source.HasNext && source.Next == ch1 || source.Next == ch2) { source.MoveNext(); if (accept) { source.Accept(); } return(true); } return(false); }
public static int ParseDigits(this IParsingContextStream source, bool accept = false) { var count = 0; while (source.HasNext && char.IsDigit(source.Next)) { count++; source.MoveNext(); } if (accept && count > 0) { source.Accept(); } return(count); }
public static int ParseWhileOneOf(this IParsingContextStream source, ISet <char> charSet, bool accept = false, IEqualityComparer <char> charComparer = null) { var count = 0; while (source.HasNext && source.Next.IsContainedBy(charSet, charComparer)) { count++; source.MoveNext(); } if (accept && count > 0) { source.Accept(); } return(count); }
public static int ParseWhile(this IParsingContextStream source, Func <char, bool> predicate, bool accept = false) { var count = 0; while (source.HasNext && predicate.Invoke(source.Next)) { count++; source.MoveNext(); } if (accept && count > 0) { source.Accept(); } return(count); }
public static bool ParseChar( this IParsingContextStream source, char ch, bool accept = false, IEqualityComparer <char> charComparer = null) { if (source.HasNext && Equals(source.Next, ch, charComparer)) { source.MoveNext(); if (accept) { source.Accept(); } return(true); } return(false); }
public static IParsingProduct TryAlternativeParse( this IEnumerable <IExpressionParser> parsers, ISourceCode src, ParsingAlternationType parsingAlternationType = ParsingAlternationType.TakeFirst, ParsingOptions options = DefaultParsingOptions) { if (parsingAlternationType == ParsingAlternationType.TakeFirst) { return(parsers.Select(p => p.TryParse(src, options)).FirstNotNullOrDefault()); } if (parsingAlternationType != ParsingAlternationType.TakeLongest && parsingAlternationType != ParsingAlternationType.TakeShortest) { throw new NotSupportedException($"{parsingAlternationType} is not supported."); } var shortest = parsingAlternationType == ParsingAlternationType.TakeShortest; var replaceCmp = shortest ? -1 : 1; IParsingContextStream selectedCtx = null; IParsingProduct result = null; foreach (var parser in parsers) { var ctx = src.GetFurtherContext(); var res = parser.TryParse(src, options); if (res != null && (result == null || replaceCmp == ctx.CompareTo(selectedCtx))) { selectedCtx?.Dispose(); selectedCtx = ctx; result = res; } } selectedCtx?.Accept(); return(result); }
/// <inheritdoc /> protected override IParsingProduct TryParseInternal(IParsingContextStream ctx, ParsingOptions options) { var res = Content.TryParse(ctx, options); if (res == null) { ctx.SetError(new ParsingError(1, $"{GroupName} expected at: '{ctx}'; {Name}")); return(null); } var overwriteExpressionType = res.ExpressionType.ValueTypeId != null && _expressionType.ValueTypeId == null; var expressionType = overwriteExpressionType ? ExpressionTypeDescriptor.Create(_expressionType.Name, res.ExpressionType.ValueTypeId, _expressionType.DefinesExpressionClass) : _expressionType; var node = ctx.Accept().CreateExpressionForAcceptedFragment( expressionType, res.ToList()); return(node); }
public static bool ParseText(this IParsingContextStream source, IEnumerable <char> text, IEqualityComparer <char> charComparer = null, bool accept = false) { foreach (var ch in text) { if (!source.MoveNext()) { return(false); } var cur = source.Current; if (!(charComparer?.Equals(ch, cur) ?? ch == cur)) { return(false); } } if (accept) { source.Accept(); } return(true); }
protected override IParsingProduct TryParseInternal(IParsingContextStream ctx, ParsingOptions options) { return(ctx.ParseChar(Character, true) ? ctx.Accept().CreateTermForAcceptedFragment(FXB.ExpressionTypes.CharTerm) : null); }
/// <summary> /// Parses the source code searching for the longest matching term text from the specified terms. /// It returns the index of the longest matching term or -1, if there is no matching term at the specified source position. /// </summary> /// <param name="source">The source of an extension.</param> /// <param name="textSelector">The selector of term text at the specified 0 based index.</param> /// <param name="accept">if set to <c>true</c> accepts the position after parsed longest text.</param> /// <param name="charComparer">The character comparer.</param> /// <param name="termsCount">The number of terms.</param> /// <returns>The index of the longest matching text or -1, if there is no matching text at the specified source position.</returns> public static int ParseLongestMatchingString(this IParsingContextStream source, int termsCount, Func <int, string> textSelector, bool accept = false, IEqualityComparer <char> charComparer = null) { var text = Enumerable.Range(0, termsCount).Select(textSelector).ToArray(); var matchedTermIdx = -1; using (var ctx = source.GetFurtherContext()) { //go through all character indexes from 0 to longest matching term // for each term check if character at specified position matches // if char matches and it is last character, temporary accept position and exclude term by setting to null // if char doesn't match -> exclude term by setting to null // if there are no more matching terms -> break // if accept true and matchedTermIdx > -1 -> accept // return matchedTermIndex var charPosition = -1; while (ctx.MoveNext()) { charPosition++; var current = ctx.Current; var matchingTermsCount = 0; for (var termIdx = 0; termIdx < text.Length; termIdx++) { var currentTerm = text[termIdx]; if (currentTerm != null) { if (currentTerm.Length <= charPosition) { text[termIdx] = null; } if (Equals(currentTerm[charPosition], current, charComparer)) { if (currentTerm.Length == charPosition + 1) { matchedTermIdx = termIdx; ctx.Accept(); text[termIdx] = null; } else { matchingTermsCount++; } } else { text[termIdx] = null; } } } if (matchingTermsCount <= 0) { break; } } } if (accept && matchedTermIdx >= 0) { source.Accept(); } return(matchedTermIdx); }
/// <inheritdoc /> protected override IParsingProduct TryParseInternal(IParsingContextStream ctx, ParsingOptions options) { return(ctx.MoveNext() && ctx.Current.IsAny(_range) ? ctx.Accept().CreateTermForAcceptedFragment(FXB.ExpressionTypes.CharTerm) : null); }