//method for insert in the expression tree with Moises Algorithm public Stack <Nodo> Insert(string er) { char[] tokens = er.ToArray(); //read character for character //Step 1. Mientras existan tokens en la expresión regular --------------------------------------- while (cts < tokens.Length) { char token = tokens[cts]; //Step 2. Obtener token --------------------------------------------- //yes false then token = st if (Is_st(token)) //Step 3. Si token es st --------------------------------------------------- { //a. Convertir st en árbol Nodo nuevo = new Nodo(); //add metho for new types the st string value_ST = GetValueNodo(tokens); nuevo.valor = value_ST;//token.ToString(); nuevo.hd = null; nuevo.hi = null; //b.Hacer “push” a la pila S con el nuevo árbol generado de st S.Push(nuevo); cts++; //next token } else if (token == '(') //Step 4. Sino Si token es “(“ ----------------------------------------- { //a. Hacer “push” a la pila T con token T.Push(token.ToString()); cts++; //next token } else if (token == ')') //Step 5. Sino Si token es “)“ ----------------------------------------- { //a. Mientras la longitud de T sea mayor que 0 y //el último dato insertado en T sea diferente de “(“ while ((T.Count() >= 0) && (T.Peek() != "(")) // se le puso mayor o igual porque si solo se le pone mayor no va entrar { //i. Si Longitud de T es igual a 0 if (T.Count() == 0) { //1. Existe error, faltan operandos S.Clear(); //Removes all objects from the Stack. return(S); //returns empty for the error } //ii. Si la longitud de S es menor a 2 if (S.Count() < 2) { //1. Existe error, faltan operandos S.Clear(); //Removes all objects from the Stack. return(S); //returns empty for the error } //iii. Hacer “pop” a T y convertirlo en árbol llamado temp Nodo temp = new Nodo(); temp.valor = T.Pop(); //iv. Hacer “pop” a S y asignarlo al hijo derecho de temp temp.hd = S.Pop(); //v. Hacer “pop” a S y asignarlo al hijo izquierdo de temp temp.hi = S.Pop(); //vi. Hacer “Push” de temp en la pila S S.Push(temp); }//end while a. //b. Hacer “pop” a T con el último dato T.Pop(); cts++; //next token } else if (Is_op(token)) //Step 6. Sino si token es op ------------------------------------------ { //a. Si op es unario if (Is_Unario(token)) { //i. Convertir op en árbol Nodo nuevo = new Nodo(); nuevo.valor = token.ToString(); nuevo.hd = null; //ii. Si la longitud de S es menor que 0 if (S.Count() <= 0) { //1. Existe error, faltan operandos S.Clear(); //Removes all objects from the Stack. return(S); //returns empty for the error } //iii. Hacer “pop” de S y asignarlo como hijo izquierdo nuevo.hi = S.Pop(); //iv. Hacer “push” a la pila S con el nuevo árbol generado de op S.Push(nuevo); } //b. Sino si T no está vacia y el “top” op en T es diferente //a “(“ y precedencia de token es menor a último op en T else if ((T.Count() > 0) && (T.Peek() != "(") && (Is_Precedence(token, T.Peek()))) //no tested precedence { //i. Extraer de T a op, convertirlo en árbol y llamarlo temp Nodo temp = new Nodo(); temp.valor = T.Pop(); //ii. Si cantidad de elementos en S es menor a 2 if (S.Count() < 2) { //1. Existe error, faltan operandos S.Clear(); //Removes all objects from the Stack. return(S); //returns empty for the error } //iii. Extraer último árbol de S y asignarlo al hijo derecho de temp temp.hd = S.Pop(); //iv. Extraer último árbol de S y asignarlo al hijo izquierdo de temp temp.hi = S.Pop(); //v. Push de temp en la pila S S.Push(temp); //si existe un pipe despues en T lo debo de concatenar si existen 2 en S if (T.Peek() == "|" && S.Count > 1 && token == '|') { //i. Extraer de T a op, convertirlo en árbol y llamarlo temp Nodo temp1 = new Nodo(); temp1.valor = T.Pop(); //iii. Extraer último árbol de S y asignarlo al hijo derecho de temp temp1.hd = S.Pop(); //iv. Extraer último árbol de S y asignarlo al hijo izquierdo de temp temp1.hi = S.Pop(); //v. Push de temp en la pila S S.Push(temp1); } } //c. Si op no es unario Hacer “push” en la pila T con token if (!Is_Unario(token)) { T.Push(token.ToString()); } cts++; //next token } // end step 6 else //Step 7. De lo contrario ---------------------------------------------------------------- { //a. Error, no es token reconocido S.Clear(); //Removes all objects from the Stack. return(S); //returns empty for the error } //Step 8. Si aún existen tokens en la expresión regular, ir a paso 2 -------------------------- }// end while step 1 //Step 9. Mientras la longitud de T sea Mayor que 0 ----------------------------------------------- while (T.Count() > 0) { //a. Hacer “pop” de T y crear un nuevo árbol llamado temp Nodo temp = new Nodo(); temp.valor = T.Pop(); //b. Si temp es “(“ if (temp.valor == "(") { //1. Existe error, faltan operandos S.Clear(); //Removes all objects from the Stack. return(S); //returns empty for the error } //c. Si longitud de S menor que 2 if (S.Count() < 2) { //1. Existe error, faltan operandos S.Clear(); //Removes all objects from the Stack. return(S); //returns empty for the error } //d. Hacer “pop” a la pila S y asignarlo como hijo derecho de temp temp.hd = S.Pop(); //e. Hacer “pop” a la pila S y asignarlo como hijo izquierdo de temp temp.hi = S.Pop(); //f. Hacer “push” a la pila S con el árbol temp S.Push(temp); } //Step 10. Si longitud de T es mayor que 0 ir a paso 9 -------------------------------------------- //Step 11. Si longitud de S es diferente de 1 ----------------------------------------------------- if (S.Count() != 1) { //1. Existe error, faltan operandos S.Clear(); //Removes all objects from the Stack. return(S); //returns empty for the error } else { //Step 12. Hacer “pop” a S y retornar el valor ---------------------------------------------------- return(S); } }//tested
}//tested //method for insert values in first and last in node that not leaf node and NUllable private void Insert_First_Last(Nodo n) { //scroll in PostOrder if (n.hi != null) { Insert_First_Last(n.hi); } if (n.hd != null) { Insert_First_Last(n.hd); } if (n.first.Count == 0) { //Rules first for Node --> depend type the valor node if (n.valor == "|") { //first = F(c1) u F(c2) foreach (var item in n.hi.first) { n.first.Add(item); } foreach (var item in n.hd.first) { n.first.Add(item); } //last = L(c1) u L(c2) foreach (var item in n.hi.last) { n.last.Add(item); } foreach (var item in n.hd.last) { n.last.Add(item); } //nullable == N(c1) ó N(c2) if (n.hi.nullable == true || n.hd.nullable == true) { n.nullable = true; } } else if (n.valor == ".") { //first = if N(c1) then F = F(c1) u F(c2) Else F = F(c1) if (n.hi.nullable == true) { foreach (var item in n.hi.first) { n.first.Add(item); } foreach (var item in n.hd.first) { n.first.Add(item); } } else { foreach (var item in n.hi.first) { n.first.Add(item); } } //last = if N(c2) then L = L(c1) u L(c2) Else L = L(c2) if (n.hd.nullable == true) { foreach (var item in n.hi.last) { n.last.Add(item); } foreach (var item in n.hd.last) { n.last.Add(item); } } else { foreach (var item in n.hd.last) { n.last.Add(item); } } //nullable == N(c1) y N(c2) if (n.hi.nullable == true && n.hd.nullable == true) { n.nullable = true; } } else if (n.valor == "*" || n.valor == "?") { //first = F = F(c1) foreach (var item in n.hi.first) { n.first.Add(item); } //last = L = L(c1) foreach (var item in n.hi.last) { n.last.Add(item); } //nullable == N n.nullable = true; } else if (n.valor == "+") { //first = F = F(c1) foreach (var item in n.hi.first) { n.first.Add(item); } //last = L = L(c1) foreach (var item in n.hi.last) { n.last.Add(item); } //nullable == FALSE for defect } } }//tested
public int cts = 0; //count tokens position //Method builder public ETree() { raiz = null; }
//Last phase for completed table the AFD Transitions public List <string> Transitions_values(List <string> t, Nodo n, List <string> v, List <string> s) { Insert_FirstStatus(s, n); Insert_Transitions(t, n, v, s); return(t); }