No das detalles de lo que llevas avanzado, pero bueno... supondremos entonces que estás al principio, es decir sabes lo que quieres hacer(o casi) pero no como lograrlo...
Como debes saber la notación postfija no precisa parçéntesis. Bien partiendo de aquí es necesario que sepas y establezcas una tabla de prioridades aplicada a los operadores...
Para no hacerlo más complejo de lo necesario supondremos que tus operadores son operadores aritméticos, es decir +, - *, / (las 4 operaciones básicas).
Como sabrás el orden de prioridad de los operadores aritméticos es 1º: multiplicación, 2º: división, 3º: suma, 4º: resta. Por tanto una expresión como: 5*2 + 3 / 3 - 6 * 2 puede de entrada ser distinto de : (5*2) + (3/3) - (6*2) y ser distinto de: (5 * 2 + 3) / (3 - (6 * 2)) , etc... por tanto a dichos operadores hay que añadir los operadores: 0º: ( , y el -1º: )
Dicho de otro modo, la tabla de prioridades es una definición de las 'normas' cuyo criterio ha de cumplir tu programa según lo esperado. Debes saber que lo que está entre paréntesis se ejecuta antes que el resto, por ello los símbolos de paréntesis deben definirse también como operadores, en este caso sólo operan prioridad, lo que implica un orden, por tanto si los defines como operadores de orden, nadie podrá decirte que no. Entendiendo correctamente estos antecedentes, ya podemos empezar a formular nuestro analizador...
..digamos que nuestro compilador tendrá al menos 2 fases claras, una que analiza las expresiones entradas y otra que después evalúa (opera con) el resultado.
Ciertamente para ello necesitamos una pila y lo mejor para todo ello es trabajar con clases, para trabajar más cómodamente cada apartado. Visual Basic no tiene una pila como objeto de programación, por tanto lo 1º será recrear una sencilla pila.
Te pongo un un ejemplo, que podrás modificar a tu gusto. nota especialmente que a esta pila le hemos dado una propiedad 'especial', al permitir que actúe como fifo, filo incluso como ambas a la vez...
Nota que el VB 6.0 lo mejor para implementar una pila es una colección. y nota también que nuestra pila es una pila genérica, por eso utilizamos elementos de tipo variant.
Si a la hora de utilizarlo tienes claro que sólo usarás un tipo de elemento, por ejemplo string, sería conveniente cambiar los prototipos a string en vez de a variant, sin embargo fíjate que es probable que necesites usar más de una pila en tu proyecto por lo que podrías necesitar realmente tener un tipo variant,... qué tal si la pila de tu proyecto usara como elementos precisamente elementos de tipo pila ???. Tendrías muchas posibilidades de un gran trabajo adelantado por una enorme sencilez antes esta posibilidad... piensa en ello detenidamente...
Public Enum enTipoPila
PILATIPO_FILO = 1 ' primero en entrar último en salir
PILATIPO_FIFO = 2 ' primero en entrar primero en salir.
PILATIPO_AMBOS = 3 ' se decide de qué extremo queremos sacar indistintamente
End Enum
Public Enum enExtremo
EXTREMO_INICIAL = 0
EXTREMO_FINAL = 1
End Enum
' =========== CAMPOS DE LAS PROPIEDADES ================
Private p_Pila As New Collection
Private p_TipoPila As enTipoPila
' =========== PROPIEDADES DE LA CLASE ==================
Public Property Get TipoPila() As enTipoPila
TipoPila = p_TipoPila
End Property
Public Property Let TipoPila(ByVal tp As enTipoPila)
p_TipoPila = tp
End Property
Public Property Get Count() As Long
Count = p_Pila.Count
End Property
'============= MÉTODOS públicos DE LA PILA =============
' la pila siempre añade al final
Public Sub Push(ByRef Elemento As Variant)
p_Pila.Add (Elemento)
End Sub
' en 'nuestra' pila podremos quitar del inio, del final o de ambos...
' es una pila 'especial'...
' extremos sólo es necesario para el caso de la pila de extraer de 'ambas partes indistintamente
Public Function Pop(Optional Extremo As enExtremo = EXTREMO_INICIAL) As Variant
If p_Pila.Count > 0 Then ' sólo si la pila tiene elementos devolvemos...
Select Case p_TipoPila
Case enTipoPila.PILATIPO_FILO
Pop = PopFilo
Case enTipoPila.PILATIPO_FIFO
Pop = PopFifo
Case enTipoPila.PILATIPO_AMBOS
'If IsMissing(Extremo) Then Extremo = EXTREMO_INICIAL '
If Extremo = EXTREMO_FINAL Then
Pop = PopFilo
Else ' toma del principio.
Pop = PopFifo
End If
End Select
Else ' quitar elementos de una colección vacía origina un error,ocasionalmente podría sustituirse por on local error resume next..
' no devuelve elementos
Pop = "No elementos"
End If
End Function
'============= MÉTODOS privados DE LA PILA =============
' pop siempre devuelve un elemento y luego lo elimina, en este caso del final
Private Function PopFilo() As Variant
PopFilo = p_Pila.Item(p_Pila.Count)
p_Pila.Remove (p_Pila.Count)
End Function
' pop siempre devuelve un elemento y luego lo elimina, en este caso del inicio.
Private Function PopFifo() As Variant
PopFifo = p_Pila.Item(1) ' las colecciones se basan en índice 1
p_Pila.Remove (1)
End Function
'============== MÉTODOS DE LA CLASE ==================
Private Sub Class_Initialize()
p_TipoPila = PILATIPO_FILO ' puesto que los valores van del 1 al 3, 0 no se admite.
End Sub
Private Sub Class_Terminate()
Set p_Pila = Nothing
End Sub
... a la tarde continúo en otro mensaje, el post será un poquito extenso... pero de momento puedes probar a mmanejar la pila