public RegExps.Expression MakeExpression(GrammarType grammarType, Action <Matrix> onBegin = null, Action <Matrix> onIterate = null) { IDictionary <NonTerminalSymbol, int> nonTerminalIndexMap = NonTerminals.Select((s, i) => new KeyValuePair <NonTerminalSymbol, int>(s, i)).ToDictionary(); RegExps.Expression[,] expressions = new RegExps.Expression[nonTerminalIndexMap.Count, nonTerminalIndexMap.Count + 1]; foreach (Rule rule in Rules) { int rowNumber = nonTerminalIndexMap[rule.Target]; foreach (Chain chain in rule.Chains) { SymbolTuple symbolTuple = GetSymbolTuple(grammarType, chain, rule.Target); RegExps.Expression expression; int columnNumber; if (symbolTuple.TerminalSymbol == null) { expression = RegExps.Empty.Instance; } else { expression = new RegExps.Symbol(symbolTuple.TerminalSymbol.Symbol); } if (symbolTuple.NonTerminalSymbol == null) { columnNumber = expressions.GetLength(1) - 1; } else { columnNumber = nonTerminalIndexMap[symbolTuple.NonTerminalSymbol]; } if (expressions[rowNumber, columnNumber] == null) { expressions[rowNumber, columnNumber] = expression; } else { expressions[rowNumber, columnNumber] = new RegExps.BinaryUnion(expression, expressions[rowNumber, columnNumber]); } } for (int i = 0; i < expressions.GetLength(1); i++) { expressions[rowNumber, i] = expressions[rowNumber, i]?.Optimize(); } } Matrix matrix = new Matrix(expressions, nonTerminalIndexMap.OrderBy(kv => kv.Value).Select(kv => kv.Key).ToList().AsReadOnly(), grammarType); return(matrix.Solve(nonTerminalIndexMap[Target], onBegin, onIterate)); }
public StateMachine MakeStateMachine(GrammarType grammarType) { ISet <Transition> transitions = new HashSet <Transition>(); ISet <Label> finalStates = new HashSet <Label>(); NonTerminalSymbol additionalState = GetNewNonTerminal(NonTerminals); switch (grammarType) { case GrammarType.Left: finalStates.Add(Target.Label); break; case GrammarType.Right: finalStates.Add(additionalState.Label); break; default: throw new NotSupportedException(string.Format(GrammarIsNotSupportedMessage, grammarType)); } foreach (Rule rule in Rules) { foreach (Chain chain in rule.Chains) { SymbolTuple symbolTuple = GetSymbolTuple(grammarType, chain, rule.Target, additionalState); if (symbolTuple.NonTerminalSymbol == null && symbolTuple.NonTerminalSymbol == null) { switch (grammarType) { case GrammarType.Left: finalStates.Add(additionalState.Label); break; case GrammarType.Right: finalStates.Add(Target.Label); break; default: throw new NotSupportedException(string.Format(GrammarIsNotSupportedMessage, grammarType)); } } else { Label currentState; Label nextState; switch (grammarType) { case GrammarType.Left: currentState = symbolTuple.NonTerminalSymbol.Label; nextState = symbolTuple.Target.Label; break; case GrammarType.Right: currentState = symbolTuple.Target.Label; nextState = symbolTuple.NonTerminalSymbol.Label; break; default: throw new NotSupportedException(string.Format(GrammarIsNotSupportedMessage, grammarType)); } transitions.Add(new Transition(currentState, symbolTuple.TerminalSymbol.Symbol, nextState)); } } } StateMachine stateMachine; switch (grammarType) { case GrammarType.Left: stateMachine = new StateMachine(additionalState.Label, finalStates, transitions); break; case GrammarType.Right: stateMachine = new StateMachine(Target.Label, finalStates, transitions); break; default: throw new NotSupportedException(string.Format(GrammarIsNotSupportedMessage, grammarType)); } return(stateMachine); }