public static ProductionRules GetFollow(ProductionRules rules) { ProductionRules first = GetFirst(rules); List <string> nonTerminals = GetNonterminals(rules); ProductionRules follow = new ProductionRules(); List <string> value = new List <string>(); for (int n = 0; n < nonTerminals.Count; ++n) { if (nonTerminals[n] == "S") { follow.Add(nonTerminals[n], "$"); } for (int item = 0; item < rules.Count; ++item) { value.AddRange(rules[item].Value.Select(d => d.ToString())); if (value.Contains(nonTerminals[n])) { for (int i = value.IndexOf(nonTerminals[n]); i < value.Count; i++) { try { if (Helper.IsLower(value[i + 1])) { follow.Add(nonTerminals[n], value[i + 1]); break; } if (Helper.IsUpper(value[i + 1])) { for (int f = 0; f < first.Count; ++f) { if (first[f].Key == value[i + 1] && first[f].Value != "*") { follow.Add(nonTerminals[n], value[i + 1]); } } } } catch (ArgumentOutOfRangeException) { var length = follow.Count; for (int f = 0; f < length; ++f) { if (follow[f].Key == rules[item].Key && value[i] != rules[item].Key) { follow.Add(nonTerminals[n], follow[f].Value); } } } } } value.Clear(); } } return(follow); }
static void Main(string[] args) { StreamReader reader = File.OpenText(@"C:\Users\Marinela\source\repos\LFPC LAB\LLParsing\rules.txt"); string line; var productions = new ProductionRules(); while ((line = reader.ReadLine()) != null) { string[] rule = line.Split("->"); productions.Add(rule[0], rule[1]); } Console.WriteLine("Initial form of the grammar:"); Helper.Display(productions); Console.WriteLine("Eliminate left recursion:"); productions.RemoveLeftRecursion(productions); Helper.Display(productions); Console.WriteLine("Obtain FIRST:"); List <KeyValuePair <string, string> > first = Parser.GetFirst(productions); Helper.Display(first); Console.WriteLine("Obtain FOLLOW:"); List <KeyValuePair <string, string> > follow = Parser.GetFollow(productions); Helper.Display(follow); }
public void ReadFromFile(string filename) { string[] lines = System.IO.File.ReadAllLines("../../Input/" + filename); Nonterminals = new HashSet <string>(lines[0].Split(' ')); Terminals = new HashSet <string>(lines[1].Split(' ')); StartSymbol = lines[2]; foreach (var line in lines.Skip(3)) { string[] elements = line.Split('?'); string[] right = elements[1].Split(' '); var produRule = new ProductionRule() { Left = elements[0], Right = right.ToList() }; ProductionRules.Add(produRule, count++); } Console.WriteLine("Terminals:"); foreach (var t in Terminals) { Console.Write(t + " "); } Console.WriteLine("\nNonterminals"); foreach (var t in Nonterminals) { Console.Write(t + " "); } Console.WriteLine("\nProduction rules"); foreach (var rule in ProductionRules) { Console.Write(rule.Key.Left + " -> " + String.Join(" ", rule.Key.Right) + " (" + rule.Value + ")"); Console.WriteLine(); } }
public static ProductionRules GetFirst(ProductionRules rules) { ProductionRules first = new ProductionRules(); List <string> value = new List <string>(); for (int item = 0; item < rules.Count; ++item) { value.AddRange(rules[item].Value.Select(d => d.ToString())); if (Helper.IsLower(value[0])) { first.Add(rules[item].Key, value[0]); } value.Clear(); } do { for (int item = 0; item < rules.Count; ++item) { value.AddRange(rules[item].Value.Select(d => d.ToString())); if (Helper.IsUpper(value[0]) && value[0] != "*") { for (int j = 0; j < first.Count; ++j) { if (first[j].Key.Contains(value[0]) && first[j].Value != "*") { first.Add(rules[item].Key, first[j].Value); } } } value.Clear(); } }while (!AllCovered(rules, first)); while (rules.Count != first.Count) { Helper.GetDistinct(first); } Helper.GetDistinct(first); return(first); }