Título: ayuda!! infijo a postfijo con 1 o mas digitos. Publicado por: isaaclm en 31 Mayo 2017, 20:22 pm hola amigos, buen dia. alguien me podria ayudar a modificar un codigo de infijo a postfijo con pilas. son 2 cosas que necesito hacer:
1.-ejemplo : Entrada : (100+5.75) + 100 -> salida : 100 5.75 + 100 +. el problema es que solo acepta caracteres de 1 solo digito. 2.- la segunda modificacion es evaluar la raiz cuadra representado por el caracter '$' con un prioridad maxima. ejemplo Entrada : $(10*10) -30 ->salida 1 : 10 10 * $ 30 - salida2 : -20 que es el resultado de la evalucacion. de antemano les agradeceria su ayuda. el codigo es el siguiente: Código
clase evaluacion postfija Código
este es el codigo de la clase pila Código
y por ultimo la clase principal la cual testea el programa. Código
Título: Re: ayuda!! infijo a postfijo con 1 o mas digitos. Publicado por: Serapis en 1 Junio 2017, 16:39 pm modificar un codigo de infijo a postfijo con pilas. son 2 cosas que necesito hacer: El primer fallo, es que pretendes operar con 1 dígito... eso esta bien en la fase de análisis léxico, para determinar correctamente los identificadores.1.-ejemplo : Entrada : (100+5.75) + 100 -> salida : 100 5.75 + 100 +. el problema es que solo acepta caracteres de 1 solo digito. Pero en una etapa superior (cuando tratas la semántica), ya debe existir una separación clara, y aunque para un sencillo problema quizás pueda no parecer adecuado tener una tabla de símbolos, lo cierto es que resuelve el problema. simplemente para casos sencillos la tabla de símbolos puede ser un simple array. En resumen ( :silbar: :silbar: :silbar: :silbar: ) : - 1º Añade una etapa a modo de analizador léxico, donde reconoces y separas convenientemente cada identificador, y donde - 2º Añadas luego el identificador a un array. Como hablamos de que es un problema sencillo, y que por ello nos basta con un usar un array, no es descabellado en estos casos, proveer un array estático, lo suficientemente grande, como albergar la expresión más compleja que pueda esperarse tratar... quizás un tamaño de 64 sea suficiente, tú decides ese tamaño. - 0º Para simplificar el analizador léxico, es adecuado anotar (crear el minilenguaje admitido) las diferentes producciones que pueden darse... es bastante sencillo, si usas BNF o alguna modificación particular. Básicamente describe que es un número, (que SIEMPRE empieza por un dígito y que está formado por 1 o más digitos y el número acaba cuando aparece un carácter distinto de dígito, dígito, operador, identificador, char, etc... numero = digito | digito || numero <--- las dos barras juntas '||' indica concatenación digito = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" <---- la barra '|' indica opcion. operador = " + "|" - "|" * "|" / "|" $ " En este ejemplo: digito es cualquiera de los números (caracteres) en el rango 0-9 y número es un digito, o un digito + un número (esto expresa recusividad, ya que número puede expresarse nuevamente con cualquiera de las dos opciones previas, esto es un digito, o un digito + otro número, etc...). Y operador es cualquiera de los caracteres indicados (inclusído tu 'raíz cuadrada'). fíjate la obligación de estar separado por espacios, es decir un operador son 3 caracteres, el que se reconoce + un espacio acada lado. Así tu analizador léxico, puede indicar error cuando no tenga un espacio a cada lado. El número no exige espacio, gracias a la última producción que falta por definir... expresión, y se define como: expresion = numero || operador || numero | numero || operador || expresion id = char | char || id <---- identificador char = "a"|"b"|"c"|"d"|"e"|"f"|"g"|"h"| ... |"y"|"z"| <---- carácter, ojo, veáse que son minúsculas, por tanto debiera generarse error en el analizador léxico, si aparece mayúsculas, ya que no se ha definido su uso en para generar los identificadores... formula = id || " = " || expresion <---- una producción sería la fórmula entera (la expresión entera, más la asignación a un identificador). A veces la 'formula' es fácil confundirlo con las producciones, debido al '=', en realidad para las producciones suele usarse el símbolo: ":=" o también "::=", yo los he usado indistintamente " = ", para explicar una producción (cualquier combinación del 'lenguaje' como una formula (una combinación específica del lenguaje que hemos llamado 'formula', espero que se sepa distinguir cuando hablo de una cosa y cuando de otra. Claramente se ve, que a una 'formula' se le asigna una expresión y es reconocida por un identificador. Por su parte una expresión consiste de una lista de números separados por un operador. Igual que número tiene 2 opciones de ser definido, se podría decir que una expresión es simple si consta de solo dos números y un operador, y una expresión es compleja si consta de una lista de números (mayor de 2), donde siempre empieza con un número y a cada número excepto al último le sigue un operador. Tu analizador léxico puede optar por indicar fallo cuando falta espacios a ambos lados del operador, o dada la simplicidad de la expresión, puedes modificarlo y añadirlo tú mismo por código (autocorreción). Nota como id (un identificador) es uno o más caracteres y que una 'formula' requiere el identificador y luego el símbolo "=", también con espacios a ambos lados. Nota que hay otra forma de expresar opciones (de una producción). Y es, usar varias líneas en vez de reunirlas en solo una, para los dígitos, los operadores y los caracteres es bastante claro el modelo de una sola línea, pero para otras, a veces queda más entendible si se usa como varias líneas, donde en cada línea se pone una sola de las opciones posibles. Un ejemplo para número (que valdría igualmente para expresión) Producción multilínea para número y expresion (es idéntico al anterior) numero = digito <--- ejemplo: 5 numero = digito || numero <---- ejemplo: 53456 expresion = numero || operador || numero <---- ejemplo: x = 5 + 3 expresion = numero || operador || expresion <---- ejemplo: y = 7 + ( 3 - 1 ) <---no hemos definido los paréntesis (en el ejemplo) como operadores, pero los he puesto para diferenciar la parte 'expresión' de esta producción. Otro ejemplo: valor = 9 - 2 + 16 Estos ejemplos en cambio actualmente darían error: valor = 44 suma = valor + 12 - 7 ...porque no hemos definido lo siguiente para formula: formula = id | id ||" = "|| expresion <--- --->ejemplos: valor = 5 h = valor total = h * cantidad total = (total + 21) preciolatas = 12 preciounitario = 32 total = total + (preciolatas * preciounitario) Este otro ejemplo daría error léxico: Valor = 5 <---- identificador no admite mayúsculas, tal como está actualmente descrito identificador. valor = 5H <---- número solo lleva dígitos, no se ha previsto diferencia de números decimales, hexadecimales, octales, binarios,etc... valor10 = 23 <--- identificador secompone solo de caracteres en el rango a-z, no puede llevar números (ni menos empezar por él), tal como está actualmente definido identificador. Hasta aquí el analizador léxico. Éste si debe operar con caracteres hasta ir formando los números (no dígitos), que deben ser añadidos a la tabla de símbolos (un array para algo sencillo basta). Si quieres profundizar en el asunto, vuelve a leer todo lo previo las veces que haga falta, si solo quieres 'aprobar el examen', te bastaba con leer este párrafo que sigue (y aplicalro bien, obviamente) :laugh: :laugh: :laugh: :laugh: Luego en la siguiente fase de análisis se puede operar ya con los tokens que contiene la tabla de símbolos. Pero ahora ya, no opera con 'chars' si no con 'strings'... sólo así, puedes hacer: valor = 534 + 723 Te recuerdo, que una de las ventajas de la notación postfija es que no exige el uso de paréntesis. y por si al final has profundizado, y le has leído varias veces, te aclaro que puede simplificarse mucho, cuando uno acaba por entender que una expresión (como la descrita, básicamente matemática) es una lista, ya que se alternan números y operadores... ..y ahí lo dejo. Te he dejado como ejercicio optimizar: expresion, formula, numero ...una de ellas es redundante, pero es ideal para ayudar a entenderlo, y una vez entendido puede ser suprimido. 2.- la segunda modificacion es evaluar la raiz cuadra representado por el caracter '$' con un prioridad maxima. ejemplo Entrada : $(10*10) -30 ->salida 1 : 10 10 * $ 30 - salida2 : -20 que es el resultado de la evalucacion. Como puedes ver, en ese mismo problema, usando la notación de postfijo (polaca inversa), no requiere el uso de paréntesis, ya que el orden en que se usan los operadores no da lugar a dudas. Ayuda mucho construir un árbol de análisis sintáctico, no es obligado, pero sí para acabar de entenderlo bien. p.d.: Nota: Se deja como ejercicio, dónde colocarías (que producción debería llevar los paréntesis y cómo sería esa producción), los paréntesis. En los operadores no se incluye paréntesis... para indicar prioridad/precedencia. Aunque la notación postfija, no requiere de paréntesis, si el analizador léxico. |