/// <summary> /// Constructor that make a copy a input Lr1Element /// </summary> public LR1Element(LR1Element inputLR1) { Left = new Token(inputLR1.Left.Content, inputLR1.Left.IsTerminal); Alpha = new List <Token>(inputLR1.Alpha); Gamma = new List <Token>(inputLR1.Gamma); Advance = new List <Token>(inputLR1.Advance); }
/// <summary> /// Construction of the first: LR1 element and node. /// </summary> /// <returns></returns> private Node GenerateFirstNode() { Production FirstProduction = Productions.First(); Node I0 = new Node(); //first LR1 element LR1Element FirstElement = new LR1Element(FirstProduction, new List <Token>() { new Token("$", true) }); I0.Elements.Add(FirstElement); I0 = Cerradura(I0); return(I0); }
/// <summary> /// Handles the expansion of Lr1 elements. /// </summary> /// <param name="CurrentNode"></param> /// <returns></returns> private Node Cerradura(Node CurrentNode) { bool SomethingIsAdded; do //repeat until there are no more new elements { SomethingIsAdded = false; foreach (LR1Element NodeItem in CurrentNode.Elements.ToList()) { //General syntax [A -> α.Bβ, {a1, a2, ..an}] if (NodeItem.Gamma.Count > 0) //only if there is something after the dot { Token B = NodeItem.Gamma.First(); if (B.IsTerminal == false) { List <Token> βa = new List <Token>(); List <Token> β = new List <Token>(NodeItem.Gamma); //Add all the Gamma tokens β.RemoveAt(0); //Except for the first token foreach (Token a in NodeItem.Advance) //Loops for all the Elements from Advance { List <Token> ResPrimAdv = new List <Token>(β); ResPrimAdv.Add(a); ResPrimAdv = Prims.GetPrimerosDe(ResPrimAdv); βa.AddRange(ResPrimAdv); //Adding GetPrimerosDe() result } βa = βa.Distinct().ToList(); //Deleting all the duplicates List <Production> BProductions = Productions.FindAll(pred => pred.Left.Content == B.Content); foreach (Production BProduction in BProductions.ToList()) { //Finds all productions of B and convert to the Lr1elements of the form [B -> .γ, b] LR1Element BLr1Token = new LR1Element(BProduction, βa); //construction B-Production if (!CurrentNode.CheckIfElementExist(BLr1Token)) { //isnt a repeated Lr1 token so its added to the elements list CurrentNode.Elements.Add(BLr1Token); SomethingIsAdded = true; } } } } } } while (SomethingIsAdded); return(CurrentNode); }
/// <summary> /// Links a node with a grammatical symbol to generate new nodes. /// </summary> /// <param name="CurrentNode"></param> /// <param name="X"></param> /// <returns></returns> private Node Ir_A(Node CurrentNode, Token X) { Node J = new Node(); // for each element [A -> α.Xβ, a] on CurrentNode foreach (LR1Element Lr1item in CurrentNode.Elements.ToList()) { if (Lr1item.Gamma.Count > 0) //only if there is something after the dot { if (Lr1item.Gamma.First().Content == X.Content) //finded { LR1Element Lr1ToAdd = new LR1Element(Lr1item); Lr1ToAdd.Alpha.Add(Lr1ToAdd.Gamma.First()); //adds X on alpha Lr1ToAdd.Gamma.RemoveAt(0); //removes X from gamma J.Elements.Add(Lr1ToAdd); } } } return(Cerradura(J)); }
/// <summary> /// Fast method that verifies if there is already an Lr1 token in the node's elements. /// </summary> /// <param name="Lr1Token"></param> /// <returns></returns> public bool CheckIfElementExist(LR1Element Lr1Token) { return(Elements.Any(pred => pred.ToString() == Lr1Token.ToString())); }
/// Ejemeplo con la información absolutamente necesaria para /// representar el siguiente AFD private void InitTestAFD() { AFD = new List <Node>(); // Tokens Token tE = new Token("E", false); Token tN = new Token("n", true); Token tP = new Token("+", true); Token tM = new Token("-", true); // Lista auxiliar para guadar tokens de anticipacion {$, +, -} // Este conjunto de tokens se repiten varias veces en este test. List <Token> commonAdvanceTokens = new List <Token>(); commonAdvanceTokens.Add(new Token("$", true)); commonAdvanceTokens.Add(tP); commonAdvanceTokens.Add(tM); // _________________________________________________________________ // Info for Node 0 // _________________________________________________________________ Node n0 = new Node(); n0.Edges.Add(1, tE); n0.Edges.Add(6, tN); // _________________________________________________________________ // Info for Node 1 // _________________________________________________________________ Node n1 = new Node(); LR1Element n1elem0 = new LR1Element(); // Node 1 Element 0 n1elem0.Left = new Token("E'", false); n1elem0.Alpha.Add(tE); n1elem0.Advance.Add(new Token("$", true)); n1.Elements.Add(n1elem0); n1.Edges.Add(2, tP); n1.Edges.Add(4, tM); // _________________________________________________________________ // Info for Node 2 // _________________________________________________________________ Node n2 = new Node(); n2.Edges.Add(3, tN); // _________________________________________________________________ // Info for Node 3 // _________________________________________________________________ Node n3 = new Node(); LR1Element n3elem0 = new LR1Element(); // Node 3 Element 0 n3elem0.Left = tE; n3elem0.Alpha.Add(tE); n3elem0.Alpha.Add(tP); n3elem0.Alpha.Add(tN); n3elem0.Advance.AddRange(commonAdvanceTokens); n3.Elements.Add(n3elem0); // _________________________________________________________________ // Info for Node 4 // _________________________________________________________________ Node n4 = new Node(); n4.Edges.Add(5, tN); // _________________________________________________________________ // Info for Node 5 // _________________________________________________________________ Node n5 = new Node(); LR1Element n5elem0 = new LR1Element(); // Node 5 Element 0 n5elem0.Left = tE; n5elem0.Alpha.Add(tE); n5elem0.Alpha.Add(tM); n5elem0.Alpha.Add(tN); n5elem0.Advance.AddRange(commonAdvanceTokens); n5.Elements.Add(n5elem0); // _________________________________________________________________ // Info for Node 6 // _________________________________________________________________ Node n6 = new Node(); LR1Element n6elem0 = new LR1Element(); // Node 6 Element 0 n6elem0.Left = tE; n6elem0.Alpha.Add(tN); n6elem0.Advance.AddRange(commonAdvanceTokens); n6.Elements.Add(n6elem0); AFD.Add(n0); AFD.Add(n1); AFD.Add(n2); AFD.Add(n3); AFD.Add(n4); AFD.Add(n5); AFD.Add(n6); }