public void VisitExplicitRule(ExplicitRule explicitRule) { foreach (var item in explicitRule) { item.Visit(this); } }
bool IsAlternativeNeeded(ExplicitRule curr, ExtensibleRule parent) { if (curr == null) { return(false); } var seq = curr.Expression as RuleExpression.Sequence; if (seq == null) { return(false); } if (seq.Childs.Count != 3) { return(false); } var arg1 = seq.Childs[0] as RuleExpression.RuleUsage; var arg2 = seq.Childs[2] as RuleExpression.RuleUsage; if (arg1 == null || arg2 == null || arg1.RuleName != parent.Name || arg2.RuleName != parent.Name) { return(false); } return(true); }
private ExplicitRule ExpandExtensibleRule(GrammarNavigator.RuleInfo ruleInfo) { ExplicitRule expandedRule; if (!_cachedExpandedRulesByPath.TryGetValue(ruleInfo.NamePath, out expandedRule)) { expandedRule = new ExplicitRule( ruleInfo.ExtRule.First().TokenId, ruleInfo.ExtRule.First().Name, new RuleExpression.Or( ruleInfo.ExtRule.SelectMany(r => r.GetAlternatives()) .OrderBy(ra => ra.Priority) .Select(ra => new RuleExpression.RuleUsage(ra.Rule.Name)) .ToArray() ) ); foreach (var attr in ruleInfo.ExtRule.SelectMany(r => r.GetAttributes())) { expandedRule.Add(attr); } _cachedExpandedRulesByPath.Add(ruleInfo.NamePath, expandedRule); } return(expandedRule); }
private GraphContext(ExplicitRule rule, RuleExpression expression, GraphContext parentContext, int invocationCount, ChildParserNodeEntry childs) { this.rule = rule; this.expression = expression; this.parentContext = parentContext; this.invocationCount = invocationCount; this.childEntries = childs; }
RuleExpression RewriteRecursionCallsImpl(ExplicitRule curr, ExplicitRule parent, bool rewrite, bool expand) { var alternativesExpr = parent.Expression as RuleExpression.Or; if (alternativesExpr == null) { throw new InvalidOperationException(); } var alternatives = alternativesExpr.Childs.Cast <RuleExpression.RuleUsage>().ToArray(); var seq = curr.Expression as RuleExpression.Sequence; if (seq == null) { return(curr.Expression); } if (seq.Childs.Count != 3) { return(curr.Expression); } var arg1 = seq.Childs[0] as RuleExpression.RuleUsage; var arg2 = seq.Childs[2] as RuleExpression.RuleUsage; if (arg1 == null || arg2 == null || arg1.RuleName != parent.Name || arg2.RuleName != parent.Name) { return(curr.Expression); } RuleExpression expr; if (rewrite) { expr = this.MakeRewrittenRecursiveExpression(alternatives, curr, seq); } else if (expand) { expr = this.MakeExpandedRecursiveExpression(alternatives, curr, seq); } else { throw new NotImplementedException(""); } return(expr); }
bool TryRewriteRecursionCalls(ExplicitRule rule, out RuleExpression expr) { expr = rule.Expression; if (_currContext.rule == null) { return(false); } GrammarNavigator.RuleInfo parentRuleInfo; if (!_nav.TryEnterRule(_nav.RuleParentScopeName, out parentRuleInfo)) { return(false); } _nav.Exit(); if (parentRuleInfo.IsExplicitRule) { return(false); } var rewrite = parentRuleInfo.ExtRule[0].GetAttributes().Any(a => a.Name == "RewriteRecursion"); var expand = parentRuleInfo.ExtRule[0].GetAttributes().Any(a => a.Name == "ExpandRecursion"); if (!(rewrite || expand)) { return(false); } if (!_cachedRewrites.TryGetValue(rule, out expr)) { //expr = RecursionRewriter.RewriteRecursionCalls(rule, this.ExpandExtensibleRule(parentRuleInfo)); expr = RewriteRecursionCallsImpl(rule, this.ExpandExtensibleRule(parentRuleInfo), rewrite, expand); _cachedRewrites.Add(rule, expr); } else { System.Diagnostics.Debug.Print("Rewrited recursion reused for rule [" + rule.Name + "]"); } return(true); }
public override bool AppliesTo(decimal number) => ExplicitRule.One(number.i( ), number.v( ));
public GraphContext ForChildExpression(RuleExpression childExpression, ExplicitRule rule = null) { return(new GraphContext(rule ?? this.rule, childExpression, this, 0, null)); }
RuleExpression MakeExpandedRecursiveExpression(RuleExpression.RuleUsage[] alternatives, ExplicitRule curr, RuleExpression.Sequence seq) { var association = Association.Left; if (curr.GetAttributes().Any(a => a.Name.ToLower() == "left")) { association = Association.Left; } if (curr.GetAttributes().Any(a => a.Name.ToLower() == "right")) { association = Association.Right; } var restAltarnatives = alternatives.SkipWhile(e => e.RuleName != curr.Name).ToArray(); RuleExpression[] leftAlts, rightAlts; switch (association) { case Association.Left: { leftAlts = restAltarnatives; rightAlts = restAltarnatives.Skip(1).ToArray(); } break; case Association.Right: { leftAlts = restAltarnatives.Skip(1).ToArray(); rightAlts = restAltarnatives; } break; default: throw new NotImplementedException(""); } return(new RuleExpression.Sequence( new RuleExpression.Or(leftAlts), seq.Childs[1], new RuleExpression.Or(rightAlts) )); }
RuleExpression MakeRewrittenRecursiveExpression(RuleExpression.RuleUsage[] alternatives, ExplicitRule curr, RuleExpression.Sequence seq) { var restAltarnatives = alternatives.SkipWhile(e => e.RuleName != curr.Name).Skip(1).ToArray(); return(new RuleExpression.Sequence( new RuleExpression.Or(restAltarnatives), new RuleExpression.MatchNumber(1, int.MaxValue, new RuleExpression.Sequence( seq.Childs[1], new RuleExpression.Or(restAltarnatives) ) ) )); }