Ejemplo n.º 1
0
        private Nonterminal Map(NonterminalExpr rule)
        {
            if (!Nonterminals.TryGetValue(rule, out var mapped))
            {
                mapped = new Nonterminal(rule.Name);
                Nonterminals.Add(rule, mapped);

                foreach (var chain in rule.Body)
                {
                    var body = new List <Symbol>();

                    foreach (var symbol in chain)
                    {
                        switch (symbol)
                        {
                        case TerminalExpr terminal:
                            body.Add(Map(terminal));
                            break;

                        case NonterminalExpr nonterminal:
                            body.Add(Map(nonterminal));
                            break;
                        }
                    }

                    Productions.Add(new Production(mapped, body));
                }
            }

            return(mapped);
        }
Ejemplo n.º 2
0
        private void MakeIsNullable()
        {
            var nullables = new HashSet <Symbol>();
            var loop      = true;

            while (loop)
            {
                loop = false;
                foreach (var rule in Nonterminals.Where(rule => !nullables.Contains(rule)))
                {
                    foreach (var production in rule.Body)
                    {
                        var count = production.Count(symbol => !nullables.Contains(symbol));

                        if (count == 0)
                        {
                            loop = nullables.Add(production.Head);
                            break;
                        }
                    }
                }
            }

            foreach (var nullable in nullables)
            {
                nullable.IsNullable = true;
            }
        }
Ejemplo n.º 3
0
 public int VerifyLLk()
 {
     for (int k = 1; k <= 10; k++)
     {
         GenerateFollowK(k);
         ParserTable.Clear();
         var result = true;
         Nonterminals.ForEach(n =>
         {
             result = result && Verify(n, k);
         });
         if (result == true)
         {
             return(k);
         }
     }
     return(-1);
 }
Ejemplo n.º 4
0
        public Grammar(
            SymbolCache <TTokenKind, Terminal <TTokenKind> > terminals,
            SymbolCache <TNonterminal, Nonterminal> nonterminals,
            Nonterminal startSymbol,
            IEnumerable <Production> productions,
            Func <Grammar <TTokenKind, TNonterminal>, IFollowSymbolsAnalyzer <TTokenKind> > analyzerFactory)
        {
            if (productions == null)
            {
                throw new ArgumentNullException(nameof(productions));
            }

            StartSymbol = startSymbol ?? throw new ArgumentNullException(nameof(startSymbol));

            Nonterminals = nonterminals ?? throw new ArgumentNullException(nameof(nonterminals));
            Terminals    = terminals ?? throw new ArgumentNullException(nameof(terminals));

            // Productions are numbered 0,1,2,...,^Productions.Count
            var prods = new List <Production>();
            // Variables (productions on the shorter form (A -> α | β | ...) are numbered 0,1,...,^Variables.Count
            var productionMap = Nonterminals.ToDictionary(symbol => symbol, _ => new List <(int, Production)>());

            int index = 0;

            foreach (var production in productions)
            {
                prods.Add(production);
                productionMap[production.Head].Add((index, production));
                index += 1;
            }

            ProductionsFor = productionMap.ToImmutableDictionary(kvp => kvp.Key,
                                                                 kvp => (IReadOnlyList <(int, Production)>)kvp.Value);

            if (prods.Count == 0)
            {
                throw new ArgumentException("The productions are empty.", nameof(productions));
            }

            Productions = prods;

            // Calculate lookahead sets (Erasable, First, Follow) using strategy provided by the caller
            _analyzer = analyzerFactory(this);
        }
Ejemplo n.º 5
0
        public void ReadFromFile(string filePath)
        {
            int number = 1;

            string[] lines = System.IO.File.ReadAllLines(@filePath);
            foreach (string line in lines)
            {
                string[] parts = line.Split("-");
                Nonterminals.Add(parts[0]);
                string[] fileProductions = parts[1].Split("|");
                var      havePoductions  = Productions.TryGetValue(parts[0], out var productions);
                if (!havePoductions)
                {
                    productions = new List <string>();
                }
                foreach (string production in fileProductions)
                {
                    productions.Add(production);
                    ProductionNumber.Add(Tuple.Create(parts[0], production), number);
                    number++;
                }
                Productions.Add(parts[0], productions);
            }
        }
Ejemplo n.º 6
0
 public Nonterminal GetNonterminal(string name)
 {
     return(Nonterminals.Where(o => o.Name == name).FirstOrDefault());
 }