Commits

Miguel Roman  committed 0617ae5

Se implemento parcialmente la generacion de la tabla sintactica.

  • Participants
  • Parent commits 145ded8

Comments (0)

Files changed (6)

File Core/Core.csproj

     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Entidades\ColumnaSintactica.cs" />
+    <Compile Include="Entidades\FilaSintactica.cs" />
     <Compile Include="Entidades\Gramatica.cs" />
     <Compile Include="Entidades\ReglaGramatical.cs" />
+    <Compile Include="Entidades\TablaSintactica.cs" />
     <Compile Include="Entidades\Terminal.cs" />
     <Compile Include="Entidades\Variable.cs" />
     <Compile Include="Servicios\GramaticaAnalyzer.cs" />

File Core/Entidades/ColumnaSintactica.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Compiladores.Entidades
+{
+    public class ColumnaSintactica
+    {
+        public Terminal Terminal { get; set; }
+        public ICollection<ReglaGramatical> Reglas { get; set; }
+
+        public ColumnaSintactica(Terminal terminal)
+        {
+            this.Terminal = terminal;
+            this.Reglas = new List<ReglaGramatical>();
+        }
+
+        public void AgregarRegla(ReglaGramatical reglaGramatical)
+        {
+            if (reglaGramatical != null && !Reglas.Contains(reglaGramatical))
+            {
+                Reglas.Add(reglaGramatical);
+            }
+        }
+    }
+}

File Core/Entidades/FilaSintactica.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Compiladores.Entidades
+{
+    public class FilaSintactica
+    {
+        public Variable Variable { get; set; }
+        public ICollection<ColumnaSintactica> Columnas { get; set; }
+
+
+        public FilaSintactica(Variable variable)
+        {
+            this.Variable = variable;
+            Columnas = new List<ColumnaSintactica>();
+        }
+
+        public ColumnaSintactica AgregarColumna(Terminal terminal)
+        {
+            var columna = Columnas.FirstOrDefault(x => x.Terminal.Equals(terminal));
+
+            if (columna == null)
+            {
+                columna = new ColumnaSintactica(terminal);
+                Columnas.Add(columna);
+            }
+
+            return columna;
+        }
+    }
+}

File Core/Entidades/TablaSintactica.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Compiladores.Entidades
+{
+    public class TablaSintactica
+    {
+
+        public ICollection<FilaSintactica> Filas { get; set; }
+
+        public TablaSintactica()
+        {
+            Filas = new List<FilaSintactica>();
+        }
+
+        public FilaSintactica AgregarFila(Variable variable)
+        {
+            var fila = Filas.FirstOrDefault(x => x.Variable.Equals(variable));
+
+            if (fila == null)
+            {
+                fila = new FilaSintactica(variable);
+                Filas.Add(fila);
+            }
+
+            return fila;
+        }
+    }
+}

File Core/Servicios/GramaticaAnalyzer.cs

         private const int IteracionesMaximas = 1000;
         private readonly Terminal epsilon = new Terminal(null);
 
-        public IEnumerable<object> Primero(IEnumerable<ReglaGramatical> reglas, Variable variable)
+        public IEnumerable<KeyValuePair<Terminal, ReglaGramatical>> Primero(IEnumerable<ReglaGramatical> reglas, Variable variable)
         {
             return PrimeroSeguro(reglas, variable, 0);
 
         }
 
-        private IEnumerable<object> PrimeroSeguro(IEnumerable<ReglaGramatical> reglas, Variable variable, int iteraciones)
+        private IEnumerable<KeyValuePair<Terminal, ReglaGramatical>> PrimeroSeguro(IEnumerable<ReglaGramatical> reglas, Variable variable, int iteraciones)
         {
             if (iteraciones > IteracionesMaximas)
             {
                 throw new StackOverflowException(string.Format("Existen reglas recursivas o que sobrepasan los {0} niveles de anidado.", IteracionesMaximas));
             }
 
-            var resultado = new List<object>();
+            var resultado = new List<KeyValuePair<Terminal, ReglaGramatical>>();
 
             // Se obtienen todas las producciones que genera la variable que se está analizando.
-            var producciones = reglas.Where(x => x.Variable.Equals(variable)).Select(x => x.Produccion).ToArray();
+            var reglasIncluidas = reglas.Where(x => x.Variable.Equals(variable)).ToArray();
 
-            foreach (var produccion in producciones)
+            foreach (var regla in reglasIncluidas)
             {
                 // Por cada una de las producciones que genere la variable, se calcula el "primero".
-                foreach (var primero in produccion)
+                foreach (var primero in regla.Produccion)
                 {
                     if (primero is Terminal)
                     {
                         // Si el primero es un terminal, se agrega el terminal al conjunto de primeros de la variable.
-                        resultado.Add(primero as Terminal);
+                        resultado.Add(new KeyValuePair<Terminal, ReglaGramatical>(primero as Terminal, regla));
                         break;
                     }
                     else if (primero is Variable)
                     {
                         // si primero es una variable, se calcula el primero de esta nueva variable y se
                         // agrega el resultado como primeros de la variable que se está analizando.
-                        var primeros = PrimeroSeguro(reglas, primero as Variable, iteraciones + 1);
+                        var primeros = PrimeroSeguro(reglas, primero as Variable, iteraciones + 1).ToList();
+
+                        foreach (var item in primeros.ToArray())
+                        {
+                            var item2 = new KeyValuePair<Terminal, ReglaGramatical>(item.Key, regla);
+                            primeros.Remove(item);
+                            primeros.Add(item2);
+                        }
+
                         resultado.AddRange(primeros);
 
                         // Si primero contiene epsilon, se calcula el primero del siguiente elemento de la
                         // producción, de lo contrario se finaliza el calculo del "primero".
-                        if (!primeros.Contains(epsilon))
+                        if (!primeros.Any(x => x.Key.Equals(epsilon)))
                         {
                             break;
                         }
             }
 
             // Se retorna el conjunto de elementos que están en primero de la variable.
-            return resultado.Distinct().OrderBy(x => x.ToString()).ToArray();
+            return resultado.Distinct().OrderBy(x => x.Key.ToString()).ToArray();
         }
 
-        public IEnumerable<object> Siguiente(IEnumerable<ReglaGramatical> reglas, Variable variable)
+        public IEnumerable<KeyValuePair<Terminal, ReglaGramatical>> Siguiente(IEnumerable<ReglaGramatical> reglas, Variable variable)
         {
             return SiguienteSeguro(reglas, variable, 0);
         }
 
-        private IEnumerable<object> SiguienteSeguro(IEnumerable<ReglaGramatical> reglas, Variable variable, int iteraciones)
+        private IEnumerable<KeyValuePair<Terminal, ReglaGramatical>> SiguienteSeguro(IEnumerable<ReglaGramatical> reglas, Variable variable, int iteraciones)
         {
             if (iteraciones > IteracionesMaximas)
             {
                 throw new StackOverflowException(string.Format("Existen reglas recursivas o que sobrepasan los {0} niveles de anidado.", IteracionesMaximas));
             }
 
-            var resultado = new List<object>();
-            resultado.Add(new Terminal("$"));
+            var resultado = new List<KeyValuePair<Terminal, ReglaGramatical>>();
+            resultado.Add(new KeyValuePair<Terminal, ReglaGramatical>(new Terminal("$"), null));
 
             // Se obtienen todas las producciones en las que se encuentre la variable que se está analizando.
             var reglasIncluidas = reglas.Where(x => x.Produccion.Contains(variable)).ToArray();
                     {
                         if (analizar)
                         {
-                            var primeroDeBeta = Primero(reglas, elemento as Variable);
-                            resultado.AddRange(primeroDeBeta.Where(x => !x.Equals(epsilon)).ToArray());
+                            if (elemento is Terminal)
+                            {
+                                // Si el primero es un terminal, se agrega el terminal al conjunto de primeros de la variable.
+                                resultado.Add(new KeyValuePair<Terminal, ReglaGramatical>(elemento as Terminal, regla));
+                                analizar = false;
+                                break;
+                            }
+
+                            var primeroDeBeta = Primero(reglas, elemento as Variable).ToList();
+
+                            foreach (var item in primeroDeBeta.ToArray())
+                            {
+                                var item2 = new KeyValuePair<Terminal, ReglaGramatical>(item.Key, regla);
+                                primeroDeBeta.Remove(item);
+                                primeroDeBeta.Add(item2);
+                            }
 
-                            if (primeroDeBeta.Contains(epsilon) && !regla.Variable.Equals(variable))
+                            resultado.AddRange(primeroDeBeta.Where(x => !x.Key.Equals(epsilon)).ToArray());
+
+                            if (primeroDeBeta.Any(x => x.Key.Equals(epsilon)) && !regla.Variable.Equals(variable))
                             {
-                                var siguienteDeA = SiguienteSeguro(reglas, regla.Variable, iteraciones + 1);
+                                var siguienteDeA = SiguienteSeguro(reglas, regla.Variable, iteraciones + 1).ToList();
+
+                                foreach (var item in siguienteDeA.ToArray())
+                                {
+                                    var item2 = new KeyValuePair<Terminal, ReglaGramatical>(item.Key, regla);
+                                    siguienteDeA.Remove(item);
+                                    siguienteDeA.Add(item2);
+                                }
+
                                 resultado.AddRange(siguienteDeA);
                             }
 
 
                     if (analizar && !regla.Variable.Equals(variable))
                     {
-                        var siguienteDeA = SiguienteSeguro(reglas, regla.Variable, iteraciones + 1);
+                        var siguienteDeA = SiguienteSeguro(reglas, regla.Variable, iteraciones + 1).ToList();
+
+                        foreach (var item in siguienteDeA.ToArray())
+                        {
+                            var item2 = new KeyValuePair<Terminal, ReglaGramatical>(item.Key, regla);
+                            siguienteDeA.Remove(item);
+                            siguienteDeA.Add(item2);
+                        }
+
                         resultado.AddRange(siguienteDeA);
                     }  
                 }
 
             return resultado.Distinct().OrderBy(x => x.ToString()).ToArray();
         }
+
+        public TablaSintactica GenerarTablaSintactica(Gramatica gramatica)
+        {
+            var tabla = new TablaSintactica();
+
+            foreach (var variable in gramatica.Variables)
+            {
+                FilaSintactica fila = tabla.AgregarFila(variable);
+
+                foreach (var terminal in gramatica.Terminales.Where(x => !x.Equals(epsilon)))
+                {
+                    fila.AgregarColumna(terminal);
+                }
+
+                fila.AgregarColumna(new Terminal("$"));
+
+                var primeroDeA = Primero(gramatica.Reglas, variable);
+                var siguienteDeA = Siguiente(gramatica.Reglas, variable);
+
+                foreach (var terminal in primeroDeA)
+                {
+                    var columna = fila.AgregarColumna(terminal.Key);
+
+                    columna.AgregarRegla(terminal.Value);
+                   
+                }
+
+                if (primeroDeA.Any(x => x.Key.Equals(epsilon)))
+                {
+                    foreach (var terminal in siguienteDeA)
+                    {
+                        var columna = fila.AgregarColumna(terminal.Key);
+                        columna.AgregarRegla(terminal.Value);
+                    }
+
+                    if (siguienteDeA.Any(x => x.Key.Equals(new Terminal("$"))))
+                    {
+                        foreach (var item in primeroDeA.Where(x => x.Key.Equals(epsilon)))
+                        {
+                            var columna = fila.AgregarColumna(new Terminal("$"));
+                            columna.AgregarRegla(item.Value);
+                        }
+                    }
+                }
+            }
+
+            return tabla;
+        }
     }
 }

File Tests/Servicios/GramaticaAnalyzerTests.cs

 using Compiladores.Entidades;
 using Compiladores.Servicios;
 using NUnit.Framework;
+using System.Linq;
 
 namespace Tests.Servicios
 {
             var primeroDeC = servicio.Primero(reglas, new Variable("C"));
             var primeroDeD = servicio.Primero(reglas, new Variable("D"));
 
-            Assert.That(primeroDeA, Is.EqualTo(new object[] { new Terminal(null), new Terminal("a"), new Terminal("b"), new Terminal("c"), new Terminal("d"), new Terminal("f") }));
-            Assert.That(primeroDeAprima, Is.EqualTo(new object[] { new Terminal(null), new Terminal("a") }));
-            Assert.That(primeroDeB, Is.EqualTo(new object[] { new Terminal(null), new Terminal("b") }));
-            Assert.That(primeroDeC, Is.EqualTo(new object[] { new Terminal(null), new Terminal("c") }));
-            Assert.That(primeroDeD, Is.EqualTo(new object[] { new Terminal(null), new Terminal("c"), new Terminal("d"), new Terminal("f") }));
+            Assert.That(primeroDeA.Select(x => x.Key).Distinct(), Is.EqualTo(new [] { new Terminal(null), new Terminal("a"), new Terminal("b"), new Terminal("c"), new Terminal("d"), new Terminal("f") }));
+            Assert.That(primeroDeAprima.Select(x => x.Key).Distinct(), Is.EqualTo(new [] { new Terminal(null), new Terminal("a") }));
+            Assert.That(primeroDeB.Select(x => x.Key).Distinct(), Is.EqualTo(new [] { new Terminal(null), new Terminal("b") }));
+            Assert.That(primeroDeC.Select(x => x.Key).Distinct(), Is.EqualTo(new [] { new Terminal(null), new Terminal("c") }));
+            Assert.That(primeroDeD.Select(x => x.Key).Distinct(), Is.EqualTo(new [] { new Terminal(null), new Terminal("c"), new Terminal("d"), new Terminal("f") }));
         }
 
         [Test]
             var siguienteDeC = servicio.Siguiente(reglas, new Variable("C"));
             var siguienteDeD = servicio.Siguiente(reglas, new Variable("D"));
 
-            Assert.That(siguienteDeA, Is.EqualTo(new object[] { new Terminal("$") }));
-            Assert.That(siguienteDeAprima, Is.EqualTo(new object[] { new Terminal("$") }));
-            Assert.That(siguienteDeB, Is.EqualTo(new object[] { new Terminal("$"), new Terminal("c") }));
-            Assert.That(siguienteDeC, Is.EqualTo(new object[] { new Terminal("$"), new Terminal("c"), new Terminal("d"), new Terminal("f") }));
-            Assert.That(siguienteDeD, Is.EqualTo(new object[] {  new Terminal("$"), new Terminal("a") }));
+            Assert.That(siguienteDeA.Select(x => x.Key).Distinct(), Is.EqualTo(new[] { new Terminal("$") }));
+            Assert.That(siguienteDeAprima.Select(x => x.Key).Distinct(), Is.EqualTo(new[] { new Terminal("$") }));
+            Assert.That(siguienteDeB.Select(x => x.Key).Distinct(), Is.EqualTo(new[] { new Terminal("$"), new Terminal("c") }));
+            Assert.That(siguienteDeC.Select(x => x.Key).Distinct(), Is.EqualTo(new[] { new Terminal("$"), new Terminal("c"), new Terminal("d"), new Terminal("f") }));
+            Assert.That(siguienteDeD.Select(x => x.Key).Distinct(), Is.EqualTo(new[] { new Terminal("$"), new Terminal("a") }));
+        }
+
+        [Test]
+        public void Siguiente_ConGramaticaDeOperaciones_RetornaSoloTerminales()
+        {
+            var gramatica = CrearGramaticaOperacionesAritmeticas();
+
+            var servicio = new GramaticaAnalyzer();
+
+            var siguienteDeE = servicio.Siguiente(gramatica.Reglas, new Variable("E"));
+            var siguienteDeEPrima = servicio.Siguiente(gramatica.Reglas, new Variable("E'"));
+            var siguienteDeT = servicio.Siguiente(gramatica.Reglas, new Variable("T"));
+            var siguienteDeTPrima = servicio.Siguiente(gramatica.Reglas, new Variable("T'"));
+            var siguienteDeF = servicio.Siguiente(gramatica.Reglas, new Variable("F"));
+
+            Assert.That(siguienteDeE.Select(x => x.Key).Distinct().ToArray(), Is.EqualTo(new[] { new Terminal("$"), new Terminal(")") }));
+            Assert.That(siguienteDeEPrima.Select(x => x.Key).Distinct().ToArray(), Is.EqualTo(new[] { new Terminal("$"), new Terminal(")") }));
+            Assert.That(siguienteDeT.Select(x => x.Key).Distinct().ToArray(), Is.EqualTo(new[] { new Terminal("$"), new Terminal(")"), new Terminal("-"), new Terminal("+") }));
+            Assert.That(siguienteDeTPrima.Select(x => x.Key).Distinct(), Is.EqualTo(new[] { new Terminal("$"), new Terminal(")"), new Terminal("-"), new Terminal("+") }));
+            Assert.That(siguienteDeF.Select(x => x.Key).Distinct().ToArray(), Is.EqualTo(new[] { new Terminal("$"), new Terminal(")"), new Terminal("*"), new Terminal("-"), new Terminal("/"), new Terminal("+") }));
+        }
+
+        [Test]
+        public void GenerarTablaSintactica_ConGramaticaSinAmbiguedad_GeneraLaTablaCorrecta()
+        {
+
+            var gramatica = CrearGramaticaOperacionesAritmeticas();
+
+            var servicio = new GramaticaAnalyzer();
+
+            var tabla = servicio.GenerarTablaSintactica(gramatica);
+
+            Assert.That(tabla.Filas.ElementAt(0).Variable, Is.EqualTo(new Variable("E")));
+            Assert.That(tabla.Filas.ElementAt(1).Variable, Is.EqualTo(new Variable("T")));
+            Assert.That(tabla.Filas.ElementAt(2).Variable, Is.EqualTo(new Variable("F")));
+            Assert.That(tabla.Filas.ElementAt(3).Variable, Is.EqualTo(new Variable("E'")));
+            Assert.That(tabla.Filas.ElementAt(4).Variable, Is.EqualTo(new Variable("T'")));
+
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(0).Terminal, Is.EqualTo(new Terminal("+")));
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(1).Terminal, Is.EqualTo(new Terminal("-")));
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(2).Terminal, Is.EqualTo(new Terminal("*")));
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(3).Terminal, Is.EqualTo(new Terminal("/")));
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(4).Terminal, Is.EqualTo(new Terminal("(")));
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(5).Terminal, Is.EqualTo(new Terminal(")")));
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(6).Terminal, Is.EqualTo(new Terminal("id")));
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(7).Terminal, Is.EqualTo(new Terminal("$")));
+
+
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(0).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(1).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(2).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(3).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(4).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("E"), Produccion = new[] { new Variable("T"), new Variable("E'") } } }));
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(5).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(6).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("E"), Produccion = new[] { new Variable("T"), new Variable("E'") } } }));
+            Assert.That(tabla.Filas.ElementAt(0).Columnas.ElementAt(7).Reglas, Is.Empty);
+
+            Assert.That(tabla.Filas.ElementAt(1).Columnas.ElementAt(0).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(1).Columnas.ElementAt(1).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(1).Columnas.ElementAt(2).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(1).Columnas.ElementAt(3).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(1).Columnas.ElementAt(4).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("T"), Produccion = new[] { new Variable("F"), new Variable("T'") } } }));
+            Assert.That(tabla.Filas.ElementAt(1).Columnas.ElementAt(5).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(1).Columnas.ElementAt(6).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("T"), Produccion = new[] { new Variable("F"), new Variable("T'") } } }));
+            Assert.That(tabla.Filas.ElementAt(1).Columnas.ElementAt(7).Reglas, Is.Empty);
+
+            Assert.That(tabla.Filas.ElementAt(2).Columnas.ElementAt(0).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(2).Columnas.ElementAt(1).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(2).Columnas.ElementAt(2).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(2).Columnas.ElementAt(3).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(2).Columnas.ElementAt(4).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("F"), Produccion = new object[] { new Terminal("("), new Variable("E"), new Terminal(")") } } }));
+            Assert.That(tabla.Filas.ElementAt(2).Columnas.ElementAt(5).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(2).Columnas.ElementAt(6).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("F"), Produccion = new[] { new Terminal("id") } } }));
+            Assert.That(tabla.Filas.ElementAt(2).Columnas.ElementAt(7).Reglas, Is.Empty);
+
+            Assert.That(tabla.Filas.ElementAt(3).Columnas.ElementAt(0).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("E'"), Produccion = new object[] { new Terminal("+"), new Variable("T"), new Variable("E'") } } }));
+            Assert.That(tabla.Filas.ElementAt(3).Columnas.ElementAt(1).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("E'"), Produccion = new object[] { new Terminal("-"), new Variable("T"), new Variable("E'") } } }));
+            Assert.That(tabla.Filas.ElementAt(3).Columnas.ElementAt(2).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(3).Columnas.ElementAt(3).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(3).Columnas.ElementAt(4).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(3).Columnas.ElementAt(5).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("E'"), Produccion = new object[] { new Terminal(null) } } }));
+            Assert.That(tabla.Filas.ElementAt(3).Columnas.ElementAt(6).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(3).Columnas.ElementAt(7).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("E'"), Produccion = new object[] { new Terminal(null) } } }));
+
+            Assert.That(tabla.Filas.ElementAt(4).Columnas.ElementAt(0).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("T'"), Produccion = new object[] { new Terminal(null) } } }));
+            Assert.That(tabla.Filas.ElementAt(4).Columnas.ElementAt(1).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("T'"), Produccion = new object[] { new Terminal(null) } } }));
+            Assert.That(tabla.Filas.ElementAt(4).Columnas.ElementAt(2).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("T'"), Produccion = new object[] { new Terminal("*"), new Variable("F"), new Variable("T'") } } }));
+            Assert.That(tabla.Filas.ElementAt(4).Columnas.ElementAt(3).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("T'"), Produccion = new object[] { new Terminal("/"), new Variable("F"), new Variable("T'") } } }));
+            Assert.That(tabla.Filas.ElementAt(4).Columnas.ElementAt(4).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(4).Columnas.ElementAt(5).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("T'"), Produccion = new object[] { new Terminal(null) } } }));
+            Assert.That(tabla.Filas.ElementAt(4).Columnas.ElementAt(6).Reglas, Is.Empty);
+            Assert.That(tabla.Filas.ElementAt(4).Columnas.ElementAt(7).Reglas, Is.EqualTo(new object[] { new ReglaGramatical { Variable = new Variable("T'"), Produccion = new object[] { new Terminal(null) } } }));
+        }
+
+        private static Gramatica CrearGramaticaOperacionesAritmeticas()
+        {
+            var gramatica = new Gramatica
+            {
+                Variables = new[] { 
+                    new Variable("E"), 
+                    new Variable("T"),
+                    new Variable("F"),
+                    new Variable("E'"), 
+                    new Variable("T'") 
+                },
+                Terminales = new[] { 
+                    new Terminal("+"),
+                    new Terminal("-"),
+                    new Terminal("*"),
+                    new Terminal("/"),
+                    new Terminal("("),
+                    new Terminal(")"),
+                    new Terminal("id"),
+                    new Terminal(null)
+                },
+                Reglas = new[] { 
+                    new ReglaGramatical{
+                        Variable = new Variable("E"),
+                        Produccion = new object [] {                            
+                            new Variable("T"),
+                            new Variable("E'")
+                        }
+                    },
+                    new ReglaGramatical{
+                        Variable = new Variable("T"),
+                        Produccion = new object [] {
+                            new Variable("F"),
+                            new Variable("T'")
+                        }
+                    },
+                    new ReglaGramatical{
+                        Variable = new Variable("F"),
+                        Produccion = new object [] {
+                            new Terminal("("),
+                            new Variable("E"),
+                            new Terminal(")") 
+                        }
+                    },
+                    new ReglaGramatical{
+                        Variable = new Variable("F"),
+                        Produccion = new object [] {
+                            new Terminal("id") 
+                        }
+                    },
+                    new ReglaGramatical{
+                        Variable = new Variable("E'"),
+                        Produccion = new object [] {
+                            new Terminal("+"),
+                            new Variable("T"),
+                            new Variable("E'")
+                        }
+                    },
+                    new ReglaGramatical{
+                        Variable = new Variable("E'"),
+                        Produccion = new object [] {
+                            new Terminal("-"),
+                            new Variable("T"),
+                            new Variable("E'")
+                        }
+                    },
+                    new ReglaGramatical{
+                        Variable = new Variable("E'"),
+                        Produccion = new object [] {
+                            new Terminal(null)
+                        }
+                    },
+                    new ReglaGramatical{
+                        Variable = new Variable("T'"),
+                        Produccion = new object [] {
+                            new Terminal("*"),
+                            new Variable("F"),
+                            new Variable("T'")
+                        }
+                    },
+                    new ReglaGramatical{
+                        Variable = new Variable("T'"),
+                        Produccion = new object [] {
+                            new Terminal("/"),
+                            new Variable("F"),
+                            new Variable("T'")
+                        }
+                    },
+                    new ReglaGramatical{
+                        Variable = new Variable("T'"),
+                        Produccion = new object [] {
+                            new Terminal(null) 
+                        }
+                    }
+                }
+            };
+            return gramatica;
         }
 
         private static ReglaGramatical[] CrearReglas()