예제 #1
0
파일: Grammar.cs 프로젝트: apodavalov/FLaG
        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();
        }
예제 #2
0
 protected bool Equals(Grammar other)
 {
     return(Terminals.SequenceEqual(other.Terminals) &&
            NonTerminals.SequenceEqual(other.NonTerminals) &&
            string.Equals(Start, other.Start) &&
            Rules.SequenceEqual(other.Rules));
 }
예제 #3
0
파일: Grammar.cs 프로젝트: apodavalov/FLaG
        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));
        }
예제 #4
0
 private bool TestTerminals()
 {
     foreach (char c in Result)
     {
         if (NonTerminals.Contains(c))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #5
0
 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);
     }
 }
예제 #6
0
        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);
        }
예제 #7
0
        /// <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());
        }
예제 #8
0
        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);
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
	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);
		}
	}
예제 #11
0
파일: Grammar.cs 프로젝트: apodavalov/FLaG
        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);
        }
예제 #12
0
 public Grammar()
 {
     Start = NonTerminals?.ElementAtOrDefault(0);
 }
예제 #13
0
 public override bool IsNonTerminal(string symbol) => NonTerminals.Contains(symbol);
예제 #14
0
        /// <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();
        }
예제 #15
0
 public int GetIndexNonTerminal(Token X) => NonTerminals.ToList().IndexOf(X.ToNonTerminalToken());
예제 #16
0
	void parseNonTerminals (NonTerminals nt) {
		foreach (Rules rule in nt.rules) {
			parseRules (rule);	
		}
	}