internal void InitSpecialRuleRef(Backend backend, ParseElementCollection parent) { Rule rule = null; switch (_type) { case SpecialRuleRefType.Null: parent.AddArc(backend.EpsilonTransition(1f)); break; case SpecialRuleRefType.Void: rule = backend.FindRule("VOID"); if (rule == null) { rule = backend.CreateRule("VOID", (SPCFGRULEATTRIBUTES)0); ((IElement)rule).PostParse((IElement)parent); } parent.AddArc(backend.RuleTransition(rule, parent._rule, 1f)); break; case SpecialRuleRefType.Garbage: { OneOf oneOf = new OneOf(parent._rule, backend); oneOf.AddArc(backend.RuleTransition(CfgGrammar.SPRULETRANS_WILDCARD, parent._rule, 0.5f)); oneOf.AddArc(backend.EpsilonTransition(0.5f)); ((IElement)oneOf).PostParse((IElement)parent); break; } } }
/// <summary> /// Returns the initial state of a special rule. /// For each type of special rule we make a rule with a numeric id and return a reference to it. /// </summary> internal void InitSpecialRuleRef(Backend backend, ParseElementCollection parent) { Rule rule = null; // Create a transition corresponding to Special or Uri switch (_type) { case SpecialRuleRefType.Null: parent.AddArc(backend.EpsilonTransition(1.0f)); break; case SpecialRuleRefType.Void: rule = backend.FindRule(szSpecialVoid); if (rule == null) { rule = backend.CreateRule(szSpecialVoid, 0); // Rule with no transitions is a void rule. ((IRule)rule).PostParse(parent); } parent.AddArc(backend.RuleTransition(rule, parent._rule, 1.0f)); break; case SpecialRuleRefType.Garbage: // Garbage transition is optional whereas Wildcard is not. So we need additional epsilon transition. OneOf oneOf = new(parent._rule, backend); // Add the garbage transition oneOf.AddArc(backend.RuleTransition(CfgGrammar.SPRULETRANS_WILDCARD, parent._rule, 0.5f)); // Add a parallel epsilon path oneOf.AddArc(backend.EpsilonTransition(0.5f)); ((IOneOf)oneOf).PostParse(parent); break; default: System.Diagnostics.Debug.Assert(false, "Unknown special ruleref type"); break; } }