public static ProductionBase <Tuple <T1, Lexeme> > Concat <T1>(this ProductionBase <T1> production1, Token token2) { CodeContract.RequiresArgumentNotNull(production1, "production1"); CodeContract.RequiresArgumentNotNull(token2, "token2"); return(from v1 in production1 from v2 in token2 select Tuple.Create(v1, v2)); }
/// <summary> /// Generates a production that converts the parsing result of another production using a specific converting rule. /// In other words, generates a 'mapping' production /// </summary> /// <typeparam name="TSource">The type of the parsing result of the source production</typeparam> /// <typeparam name="TResult">The type of the converted parsing result</typeparam> /// <param name="production">The source production whose parsing result will be converted</param> /// <param name="selector">The delegate that represents the converting rule</param> /// <returns>The generated 'mapping' production object</returns> /// <example> /// The following code converts the parsing result of <see cref="Production{int}"/> into string from int. /// <code language="C#"> /// Production<int> intProduction = new Production<int>(); /// /// var stringProduction = /// from iv in intProduction /// select iv.ToString(); /// </code> /// </example> public static ProductionBase <TResult> Select <TSource, TResult>(this ProductionBase <TSource> production, Func <TSource, TResult> selector) { CodeContract.RequiresArgumentNotNull(production, "production"); CodeContract.RequiresArgumentNotNull(selector, "selector"); return(new MappingProduction <TSource, TResult>(production, selector)); }
private void PerformPanicRecovery(Lexeme z, List <ParserHead> shiftedHeads) { //Panic recovery //to the 1st head: //pop stack until there's a state S, which has a Goto action of a non-terminal A //discard input until there's an token a in Follow(A) //push Goto(s, A) into stack //discard all other heads m_heads.Clear(); m_heads.AddRange(shiftedHeads.Where(h => h.ErrorRecoverLevel == 0)); shiftedHeads.Clear(); ParserHead errorHead1 = m_errorCandidates[0]; m_errorCandidates.Clear(); IProduction p = errorHead1.PanicRecover(m_transitions, z.Value.Span, z.IsEndOfStream); ProductionBase productionBase = p as ProductionBase; if (productionBase != null) { var follow = productionBase.Info.Follow; m_heads.Add(errorHead1); throw new PanicRecoverException(follow); } }
public static ProductionBase <T> Union <T>(this ProductionBase <T> production1, ProductionBase <T> production2) { CodeContract.RequiresArgumentNotNull(production1, "production1"); CodeContract.RequiresArgumentNotNull(production2, "production2"); return(new AlternationProduction <T>(production1, production2)); }
public static ProductionBase <IEnumerable <T> > Many1 <T, TSeparator>(this ProductionBase <T> production, ProductionBase <TSeparator> separator) { CodeContract.RequiresArgumentNotNull(production, "production"); return(from r in production from rm in production.PrefixedBy(separator).Many() select new RepeatParserListNode <T>(r, rm as RepeatParserListNode <T>) as IEnumerable <T>); }
public static ProductionBase <TResult> SelectMany <T1, TResult>(this ProductionBase <T1> production, Func <T1, Token> productionSelector, Func <T1, Lexeme, TResult> resultSelector) { CodeContract.RequiresArgumentNotNull(production, "production"); CodeContract.RequiresArgumentNotNull(productionSelector, "productionSelector"); CodeContract.RequiresArgumentNotNull(resultSelector, "resultSelector"); return(new ConcatenationProduction <T1, Lexeme, TResult>(production, v => productionSelector(v).AsTerminal(), resultSelector)); }
/// <summary> /// Generates a production that concatenates two productions. The generated 'concatenation' production consumes the input of two source productions in the order, /// and then using a converting rule to convert the parsing results of two source productions. In practice, this method is used to build multiple embedded 'from' /// clauses in a Linq query expression to concatenate multiple source productions. /// </summary> /// <typeparam name="T1">The type of the parsing result of the 1st source production</typeparam> /// <typeparam name="T2">The type of the parsing result of the 2nd source production</typeparam> /// <typeparam name="TResult">The parsing result of the 'concatentation' production</typeparam> /// <param name="production">The 1st source production</param> /// <param name="productionSelector">The delegate used to generated the 2nd source production. /// Note that the argument of this delegate will be always null (Nothing in Visual Basic)</param> /// <param name="resultSelector">The delegate that represents the converting rule of parsing result</param> /// <returns>The generated 'concatentation' production object</returns> /// <example> /// The following code concatenates two <see cref="Production{T}"/> and formats the parsing result. /// <code language="C#"> /// Production<string> strProduction = new Production<string>(); /// Production<int> intProduction = new Production<int>(); /// /// var concatenation = /// from sv in strProduction /// from iv in intProduction /// select String.Format("{0} is followed by {1}", sv, iv); /// </code> /// </example> public static ProductionBase <TResult> SelectMany <T1, T2, TResult>(this ProductionBase <T1> production, Func <T1, ProductionBase <T2> > productionSelector, Func <T1, T2, TResult> resultSelector) { CodeContract.RequiresArgumentNotNull(production, "production"); CodeContract.RequiresArgumentNotNull(productionSelector, "productionSelector"); CodeContract.RequiresArgumentNotNull(resultSelector, "resultSelector"); return(new ConcatenationProduction <T1, T2, TResult>(production, productionSelector, resultSelector)); }
public AlternationProduction(ProductionBase <T> production1, ProductionBase <T> production2) { CodeContract.RequiresArgumentNotNull(production1, "production1"); CodeContract.RequiresArgumentNotNull(production2, "production2"); Production1 = production1; Production2 = production2; }
public ConcatenationProduction(ProductionBase <T1> productionLeft, Func <T1, ProductionBase <T2> > productionRightSelector, Func <T1, T2, TR> selector) { CodeContract.RequiresArgumentNotNull(productionLeft, "productionLeft"); CodeContract.RequiresArgumentNotNull(productionRightSelector, "productionRightSelector"); CodeContract.RequiresArgumentNotNull(selector, "selector"); ProductionLeft = productionLeft; ProductionRight = productionRightSelector(default(T1)); Selector = selector; }
public MappingProduction(ProductionBase <TSource> sourceProduction, Func <TSource, TReturn> selector, Func <TReturn, bool> validationRule, int?errorId, Func <TReturn, SourceSpan> positionGetter) { CodeContract.RequiresArgumentNotNull(sourceProduction, "sourceProduction"); CodeContract.RequiresArgumentNotNull(selector, "selector"); SourceProduction = sourceProduction; Selector = selector; ValidationRule = validationRule; ValidationErrorId = errorId; PositionGetter = positionGetter; }
public static ProductionBase <Lexeme> Union(params Token[] tokens) { CodeContract.RequiresArgumentInRange(tokens.Length > 0, "tokens", "There must be at least on token to be unioned"); ProductionBase <Lexeme> result = tokens[0].AsTerminal(); for (int i = 1; i < tokens.Length; i++) { result = new AlternationProduction <Lexeme>(result, tokens[i].AsTerminal()); } return(result); }
public static ProductionBase <T> Union <T>(params ProductionBase <T>[] productions) { CodeContract.RequiresArgumentInRange(productions.Length > 0, "productions", "There must be at least one production to be unioned"); ProductionBase <T> result = productions[0]; for (int i = 1; i < productions.Length; i++) { result = new AlternationProduction <T>(result, productions[i]); } return(result); }
public static ProductionBase <IEnumerable <T> > Many1 <T>(this ProductionBase <T> production) { CodeContract.RequiresArgumentNotNull(production, "production"); Production <IEnumerable <T> > many1 = new Production <IEnumerable <T> >(); var many = Empty(new RepeatParserListNode <T>() as IEnumerable <T>) | many1; many1.Rule = from r in production from rm in many select new RepeatParserListNode <T>(r, rm as RepeatParserListNode <T>) as IEnumerable <T>; return(many1); }
public static ProductionBase <TResult> Where <TResult>(this ProductionBase <TResult> production, Expression <Func <TResult, bool> > predicate) { CodeContract.RequiresArgumentNotNull(production, "production"); CodeContract.RequiresArgumentNotNull(predicate, "predicate"); Expression <Func <TResult, bool> > finalRule = null; Expression <Func <TResult, SourceSpan> > positionGetter = null; int?errorId = null; //exptract the first layer of 'predicate' if (predicate.Body.NodeType == ExpressionType.Call) { MethodCallExpression call = predicate.Body as MethodCallExpression; if (call.Method.Equals(s_checkMethod)) { //it is the call to Grammar.Check, extract message var ruleExp = call.Arguments[0]; var errIdExp = call.Arguments[1]; var positionExp = call.Arguments[2]; positionGetter = Expression.Lambda <Func <TResult, SourceSpan> >(positionExp, predicate.Parameters[0]); Expression <Func <int> > idGetter = Expression.Lambda <Func <int> >(errIdExp); errorId = idGetter.Compile()(); finalRule = Expression.Lambda <Func <TResult, bool> >(ruleExp, predicate.Parameters[0]); } } if (finalRule == null) { finalRule = predicate; } return(new MappingProduction <TResult, TResult>(production, x => x, finalRule.Compile(), errorId, positionGetter != null ? positionGetter.Compile() : null)); }
private void PerformPanicRecovery(Lexeme z, List <ParserHead> shiftedHeads) { //Panic recovery //to the 1st head: //pop stack until there's a state S, which has a Goto action of a non-terminal A //discard input until there's an token a in Follow(A) //push Goto(s, A) into stack //discard all other heads m_heads.Clear(); m_heads.AddRange(shiftedHeads.Where(h => h.ErrorRecoverLevel == 0)); shiftedHeads.Clear(); ParserHead errorHead1 = m_errorCandidates[0]; m_errorCandidates.Clear(); var candidates = errorHead1.PanicRecover(m_transitions, z.Value.Span, z.IsEndOfStream); ISet <IProduction> follows = new HashSet <IProduction>(); foreach (var candidate in candidates) { ProductionBase p = candidate.Item2 as ProductionBase; follows.UnionWith(p.Info.Follow); m_heads.Add(candidate.Item1); } if (m_heads.Count > 0) { throw new PanicRecoverException(follows); } else { throw new ParsingFailureException("There's no way to recover from parser error"); } }
public MappingProduction(ProductionBase <TSource> sourceProduction, Func <TSource, TReturn> selector) : this(sourceProduction, selector, null, null, null) { }
public static ProductionBase <T> PackedBy <T>(this ProductionBase <T> production, Token prefix, Token suffix) { return(from pr in prefix from p in production from s in suffix select p); }
public static ProductionBase <T2> Second <T1, T2>(this ProductionBase <Tuple <T1, T2> > tupleProduction) { CodeContract.RequiresArgumentNotNull(tupleProduction, "tupleProduction"); return(tupleProduction.Select(t => t.Item2)); }
public static ProductionBase <T> SuffixedBy <T>(this ProductionBase <T> production, Token suffix) { return(from p in production from s in suffix select p); }
public static ProductionBase <T> PackedBy <T, TPrefix, TSuffix>(this ProductionBase <T> production, ProductionBase <TPrefix> prefix, ProductionBase <TSuffix> suffix) { return(from pr in prefix from p in production from s in suffix select p); }
public static ProductionBase <T> PrefixedBy <T>(this ProductionBase <T> production, Token prefix) { return(from pr in prefix from p in production select p); }
public static ProductionBase <T> Optional <T>(this ProductionBase <T> production) { CodeContract.RequiresArgumentNotNull(production, "production"); return(production.Union(Empty(default(T)))); }
public static ProductionBase <IEnumerable <Lexeme> > Many1 <TSeparator>(this Token token, ProductionBase <TSeparator> separator) { CodeContract.RequiresArgumentNotNull(token, "token"); return(token.AsTerminal().Many1(separator)); }
public static ProductionBase <IEnumerable <T> > Many1 <T>(this ProductionBase <T> production, Token seperator) { CodeContract.RequiresArgumentNotNull(production, "production"); return(production.Many1(seperator.AsTerminal())); }
public static ProductionBase <IEnumerable <T> > Many <T, TSeparator>(this ProductionBase <T> production, ProductionBase <TSeparator> separator) { CodeContract.RequiresArgumentNotNull(production, "production"); return(Empty(new RepeatParserListNode <T>() as IEnumerable <T>).Union(production.Many1(separator))); }