void posfijo(char *colaE,pila_tipo_dato *pilaOP, char *numactual,int fin_linea ){ char oper='\0'; //auxiliar int Boolinsert=0; char sep='#'; if (esOperador(numactual)==0){ //quiere decir que es operando o numero if (fin_linea==1){ //simbolo terminal while(pilaOP->cant_element!=0){ char quitar; pila_desapilar(pilaOP,&quitar); strcat(colaE,&quitar); } } else{ strcat(colaE,numactual); strcat(colaE,&sep); } } if(esOperador(numactual)==1) { //3.1) Si la pila esta vacía o el operador tiene mayor prioridad //que el que está en la cima de la pila (o bien es la máxima prioridad), //se mete en la pila. if (pilaOP->cant_element>0){ pila_getfrente(pilaOP,&oper); if (precedencia(numactual)>precedencia(&oper)){ pila_apilar(pilaOP,numactual); Boolinsert=1; } } if (pilaOP->cant_element==0){ pila_apilar(pilaOP,numactual); Boolinsert=1; } //3.2) Si la prioridad es menor o igual, el operador se saca de la pila, //se mete en la expresión postfija y se vuelve a hacer la comparación con //el nuevo elemento de la cima de la pila. if(Boolinsert==0 && pilaOP->cant_element>0) { pila_getfrente(pilaOP,&oper); while(precedencia(numactual)<=precedencia(&oper)&& pilaOP->cant_element>0 ){ char quitar; pila_desapilar(pilaOP,&quitar); strcat(colaE,&quitar); pila_getfrente(pilaOP,&oper); } pila_apilar(pilaOP,numactual); } } }
int main(){ Pilha *posfixa = criaPilha(); Pilha *operadores = criaPilha(); Pilha *infixa = criaPilha(); char inf[MAX],letra,t; int testes,n,i,j,f=0; scanf("%d",&testes); while(testes > 0){ testes--; scanf("%s",&inf); n = strlen(inf); for(i = n-1;i>=0;i--){ Push(infixa,inf[i]); } while(!isEmpty(infixa)) { Pop(infixa,&letra); if(letra != '+' && letra != '-' && letra != '*' && letra != '/' && letra != '^' && letra != '(' && letra != ')'){ Push(posfixa,letra); }else if(letra == '('){ Push(operadores,letra); }else if(letra == ')'){ desempilha(posfixa,operadores); }else{ while(precedencia(Topo(operadores)) > precedencia(letra) || precedencia(Topo(operadores)) == precedencia(letra)){ Pop(operadores,&t); Push(posfixa,t); } Push(operadores,letra); } } if(!isEmpty(operadores)) { desempilha_op(posfixa,operadores); } exibe(posfixa); Empty(posfixa); Empty(operadores); }; return 0; }
string uParser::TMaxParser::infijaToPosfija(string infija) { stack<string> pila; string posfija; string term; Termino tipo; while(!(term = nextTerm(infija, tipo)).empty()) { switch(tipo) { case tNumero: case tVariable: posfija += " " + term; break; case tOperador: while(pila.size() > 0 && string::npos != aOperadores->find(pila.top()[0]) && precedencia(pila.top()[0], term[0])) { posfija += " " + pila.top(); pila.pop(); } pila.push(term); break; case tFunction: //TODO: Si arreglamos esto ya tomaria funciones de un parámetro while(pila.size() > 0 /*&& string::npos != aOperadores->find(pila.top()) && precedencia(pila.top()[0], term[0])*/) { posfija += " " + pila.top(); pila.pop(); } pila.push(term); break; case tOpen: pila.push(term); break; case tClose: while(!pila.empty() && pila.top()[0]!='(') { posfija += " " + pila.top(); pila.pop(); } if(pila.top()[0] == '(') pila.pop(); break; case tDesconocido: default: break; } } while(pila.size() > 0) { posfija += " " + pila.top(); pila.pop(); } return posfija; }
/* Busca dentro de una exprecion el operador que tiene mayor precedencia, es decir, el que se resolvera al final y devuelve su indice dentro de la exprecion. */ int max_precedencia(char *prop, int ini, int fin) { int npar=0, prec=0, anid=0, index=0; bool prim=true; for(int i=ini; i<fin; i++) { if(prop[i] == '(') { npar++; } else if(prop[i] == ')') { npar--; } else { if(npar<0) return -1; //error de sintaxis int p = precedencia(prop[i]); if(prim) { anid = npar; prec = p; index = i; prim = false; continue; } if(npar<anid) { anid = npar; prec = p; index = i; } else if(anid==npar) { if(p>prec) { prec = p; index = i; } else if(p==prec) { if(prop[index] != prop[i]) return -1; //error de doble interpretacion if(prop[index] != '!') index = i; } } } } if(npar != 0 || prim) return -1; //error de sintaxis return index; }