public Grammar(IEnumerable <Rule> rules, NonTerminalSymbol target) { if (rules == null) { throw new ArgumentNullException(nameof(rules)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } if (rules.AnyNull()) { throw new ArgumentException("At least one rule is null."); } Rules = Normalize(rules).AsReadOnly(); Alphabet = Rules.SelectMany(rule => rule.Alphabet).ToSortedSet().AsReadOnly(); Target = target; ISet <NonTerminalSymbol> nonTerminals = Rules.SelectMany(rule => rule.NonTerminals).ToSortedSet(); nonTerminals.Add(Target); NonTerminals = nonTerminals.AsReadOnly(); Symbols = NonTerminals.OfType <Symbol>().Intersect(Alphabet).ToSortedSet().AsReadOnly(); }
protected bool Equals(Grammar other) { return(Terminals.SequenceEqual(other.Terminals) && NonTerminals.SequenceEqual(other.NonTerminals) && string.Equals(Start, other.Start) && Rules.SequenceEqual(other.Rules)); }
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)); }
private bool TestTerminals() { foreach (char c in Result) { if (NonTerminals.Contains(c)) { return(false); } } return(true); }
public override int GetHashCode() { unchecked { var hashCode = (Terminals != null ? Terminals.Aggregate(new int(), (i, s) => { i += s.GetHashCode(); return(i); }) : 0); hashCode = (hashCode * 397) ^ (NonTerminals != null ? NonTerminals.Aggregate(new int(), (i, s) => { i += s.GetHashCode(); return(i); }) : 0); hashCode = (hashCode * 397) ^ (Start != null ? Start.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (Rules != null ? Rules.Aggregate(new int(), (i, s) => { i += s.GetHashCode(); return(i); }) : 0); return(hashCode); } }
public NonTerminal GetNonTerminal(PSMComponent psmComponent) { NonTerminal nonTerminal; if (!NonTermialsDictionary.TryGetValue(psmComponent, out nonTerminal)) { nonTerminal = new NonTerminal(psmComponent); if (!Exolutio.SupportingClasses.NameSuggestor <NonTerminal> .IsNameUnique(NonTerminals, nonTerminal.ToString(), n => n.ToString())) { string name = Exolutio.SupportingClasses.NameSuggestor <NonTerminal> .SuggestUniqueName(NonTerminals, nonTerminal.ToString(), n => n.ToString(), true, false); nonTerminal.UniqueName = name; } NonTermialsDictionary[psmComponent] = nonTerminal; NonTerminals.Add(nonTerminal); } return(nonTerminal); }
/// <summary> /// Получение цикличных правил /// </summary> /// <returns></returns> private string[] GetCycleRules() { var cycleRules = new List <string>(); foreach (var rule in Rules) { //Разделяем правило на левую и правую сторону var result = GetRuleParts(rule); //Если правая часть правила равна какому - либо нетерминалу (кроме себя), //получаем цикличное правило if (NonTerminals.Where(p => p != result[0]).Contains(result[1])) { cycleRules.Add(rule); } } return(cycleRules.ToArray()); }
public Term[,] GenerateTable() { Table = new Term[NonTerminals.Count(), Terminals.Count()]; foreach (var term in _terms) { var A = GetIndexNonTerminal(term.Caller); foreach (var production in term.Productions) { var first = production.FirstToken; var f = first.IsTerminal() || first.IsEmpty() ? new First(term.Caller, new List <TerminalToken> { first.ToTerminalToken() }) : _firsts.Single(x => x.NonTerminal == first); foreach (var terminal in f.Terminals) { var a = GetIndexTerminal(terminal); var t = new Term(term.Caller, production); if (terminal.Value == "ε") { var follow = _follows.Single(x => x.NonTerminal == term.Caller); foreach (var followTerminal in follow.Terminals) { var b = GetIndexTerminal(followTerminal); PopulateTable(A, b, t); } } else if (A >= 0 && a >= 0) { PopulateTable(A, a, t); } } } } return(Table); }
/// <summary> /// Build all rules for nonterminal /// </summary> /// <param name="grammarRuleContext"></param> private void BuildGrammarRule(GrammarRuleContext grammarRuleContext) { string name = grammarRuleContext.grammarName().GetText(); //save start rule if (firstRuleName.Equals("")) { firstRuleName = name; } if (NonTerminals.ContainsKey(name)) { throw new GrammarBuilderException($"Nonterminal {name} is defined twice"); } var nonTerminal = NonTerminals[name] = new NonTerminal(name); ProductionsContext productions = grammarRuleContext.productions(); do { nonTerminal.Productions.Add(BuildProduction(productions.production())); productions = productions.productions(); } while (productions != null); }
void parseExpansion(string word, Rules rule){ /*IEnumerable<string> words = SplitAndKeep (word, delimiters); int length = 0; foreach (String w in words) { string x = w; x = x+x; length++; } foreach (String w in words) { if (w != "[" && w != "]") { if (length == 3) { rule.newExpansion.Add(w); } else if (length == 5) { NonTerminals test = new NonTerminals (); comment.nonTerms.TryGetValue (w, out test); rule.newExpansion.Add(test); } else { rule.newExpansion.Add(w); } } }*/ if (word.Contains ("[[")) { char[] t = { '[', ']' }; word = word.Trim (t); NonTerminals test = new NonTerminals (); comment.nonTerms.TryGetValue (word, out test); rule.newExpansion.Add(test); } else if (word.Contains ("[")) { char[] t = { '[', ']' }; word = word.Trim (t); rule.newExpansion.Add(word); } else { rule.newExpansion.Add(word); } }
public bool RemoveChainRules(out Grammar grammar, Action <ChainRulesBeginPostReport> onBegin = null, Action <ChainRulesIterationPostReport> onIterate = null, Action <ChainRulesEndPostReport> onEnd = null) { IDictionary <NonTerminalSymbol, ISet <NonTerminalSymbol> > newSymbolSetMap = NonTerminals.ToDictionary(s => s, s => new HashSet <NonTerminalSymbol>(s.AsSequence()).Of <ISet <NonTerminalSymbol> >()); IDictionary <NonTerminalSymbol, ChainRulesEndTuple> unchangeableSymbolSetMap = new Dictionary <NonTerminalSymbol, ChainRulesEndTuple>(); IDictionary <NonTerminalSymbol, Rule> targetRuleMap = Rules.ToDictionary(r => r.Target); if (onBegin != null) { onBegin(new ChainRulesBeginPostReport(0, newSymbolSetMap)); } int i = 0; do { i++; IDictionary <NonTerminalSymbol, ISet <NonTerminalSymbol> > nextSymbolSetMap = newSymbolSetMap; newSymbolSetMap = nextSymbolSetMap.Keys.ToDictionary(s => s, s => new HashSet <NonTerminalSymbol>().Of <ISet <NonTerminalSymbol> >()); foreach (KeyValuePair <NonTerminalSymbol, ISet <NonTerminalSymbol> > nextSymbolSet in nextSymbolSetMap) { foreach (NonTerminalSymbol nonTerminalSymbol in nextSymbolSet.Value) { if (targetRuleMap.ContainsKey(nonTerminalSymbol)) { Rule rule = targetRuleMap[nonTerminalSymbol]; foreach (Chain chain in rule.Chains.Where(c => c.Sequence.Count == 1)) { NonTerminalSymbol symbol = chain.Sequence.First().As <NonTerminalSymbol>(); ISet <NonTerminalSymbol> newSymbolSet = newSymbolSetMap[nextSymbolSet.Key]; if (symbol != null && !newSymbolSet.Contains(symbol) && !nextSymbolSet.Value.Contains(symbol)) { newSymbolSet.Add(symbol); } } } } } IDictionary <NonTerminalSymbol, ISet <NonTerminalSymbol> > previousSymbolSetMap = nextSymbolSetMap.ToDictionary(kv => kv.Key, kv => kv.Value.ToHashSet().Of <ISet <NonTerminalSymbol> >()); IDictionary <NonTerminalSymbol, ChainRulesIterationTuple> symbolMap = new Dictionary <NonTerminalSymbol, ChainRulesIterationTuple>(); foreach (KeyValuePair <NonTerminalSymbol, ISet <NonTerminalSymbol> > symbolSet in previousSymbolSetMap) { ISet <NonTerminalSymbol> newSymbolSet = newSymbolSetMap[symbolSet.Key]; ISet <NonTerminalSymbol> nonTerminalSet = nextSymbolSetMap[symbolSet.Key]; if (newSymbolSet.Count == 0) { unchangeableSymbolSetMap[symbolSet.Key] = new ChainRulesEndTuple(nonTerminalSet, nonTerminalSet.Where(m => m != symbolSet.Key), i); symbolMap.Add(symbolSet.Key, new ChainRulesIterationTuple(true, symbolSet.Value, newSymbolSet, nonTerminalSet)); nextSymbolSetMap.Remove(symbolSet.Key); } else { ISet <NonTerminalSymbol> nextSymbolSet = nonTerminalSet; nextSymbolSet.UnionWith(newSymbolSet); symbolMap.Add(symbolSet.Key, new ChainRulesIterationTuple(false, symbolSet.Value, newSymbolSet, nextSymbolSet)); } } if (onIterate != null) { onIterate(new ChainRulesIterationPostReport(i, symbolMap, symbolMap.All(kv => kv.Value.IsLastIteration))); } newSymbolSetMap = symbolMap.Where(kv => !kv.Value.IsLastIteration).ToDictionary(kv => kv.Key, kv => kv.Value.Next.ToHashSet().Of <ISet <NonTerminalSymbol> >()); } while (newSymbolSetMap.Count > 0); ISet <Rule> newRules = new HashSet <Rule>(); foreach (Rule rule in Rules) { ISet <Chain> newChains = new HashSet <Chain>(); foreach (Chain chain in rule.Chains) { if (chain.Sequence.Count != 1 || chain.Sequence.FirstOrDefault().As <NonTerminalSymbol>() == null) { newChains.Add(chain); } } if (newChains.Any()) { newRules.Add(new Rule(newChains, rule.Target)); } } if (onEnd != null) { onEnd(new ChainRulesEndPostReport(unchangeableSymbolSetMap)); } ISet <Rule> additionalRules = new HashSet <Rule>(); foreach (Rule rule in newRules) { foreach (KeyValuePair <NonTerminalSymbol, ChainRulesEndTuple> symbolSet in unchangeableSymbolSetMap) { if (symbolSet.Value.FinalNonTerminals.Contains(rule.Target)) { additionalRules.Add(new Rule(rule.Chains, symbolSet.Key)); } } } newRules = Normalize(newRules.Concat(additionalRules)); if (!newRules.SetEquals(Rules)) { grammar = new Grammar(newRules, Target); return(true); } grammar = this; return(false); }
public Grammar() { Start = NonTerminals?.ElementAtOrDefault(0); }
public override bool IsNonTerminal(string symbol) => NonTerminals.Contains(symbol);
/// <summary> /// Initialize NonTerminals and Terminals with rules. /// /// </summary> public void Build() { GrammarFileGrammarLexer speakLexer = new GrammarFileGrammarLexer(inputStream); CommonTokenStream commonTokenStream = new CommonTokenStream(speakLexer); GrammarFileGrammarParser grammarParser = new GrammarFileGrammarParser(commonTokenStream); foreach (var line in grammarParser.file().line()) { if (line.lexerRule() != null) { BuildLexerRule(line.lexerRule()); } else { BuildGrammarRule(line.grammarRule()); } } InputStartNonTerminal = StartNonTerminal = NonTerminals[firstRuleName]; if (NonTerminals.ContainsKey("startRule")) { throw new Exception("The name \"startRule\" is reserved, change the name for this nonterminal"); } NonTerminals.Add("startRule", new NonTerminal("startRule")); NonTerminals["startRule"].AddRule(new Production(productionRuleID++, new NonTerminalProduction(firstRuleName))); firstRuleName = "startRule"; StartNonTerminal = NonTerminals[firstRuleName]; ///Checking, that we have all terminals and nonterminals, which was mentioned in rules foreach (var nonTerminals in NonTerminals.Values) { foreach (var rule in nonTerminals.Productions) { foreach (var element in rule.ProductionElements) { if (element is TerminalProduction) { var e = element as TerminalProduction; if (e.needSetTerminal) { if (!Terminals.ContainsKey(e.Name)) { throw new Exception($"Nonterminal {e} is not defined"); } e.Terminal = Terminals[e.Name]; } } else if (element is NonTerminalProduction) { var e = element as NonTerminalProduction; if (!NonTerminals.ContainsKey(e.Name)) { throw new Exception($"Nonterminal {e} is not defined"); } e.NonTerminal = NonTerminals[e.Name]; } } } } //Calculate FIRST and FOLLOW for each nonterminal //First: CalculateFirst(); //Follow CalculateFollow(); }
public int GetIndexNonTerminal(Token X) => NonTerminals.ToList().IndexOf(X.ToNonTerminalToken());
void parseNonTerminals (NonTerminals nt) { foreach (Rules rule in nt.rules) { parseRules (rule); } }