Compilador escrito en Java: Implementación de optimizador de mirilla

Estoy escribiendo un compilador para un subconjunto de Pascal. El compilador produce instrucciones de máquina para una máquina confeccionada. Quiero escribir un optimizador de mirilla para este lenguaje de máquina, pero tengo problemas para sustituir algunos de los patrones más complicados.

Especificación del optimizador de mirilla

He investigado varios enfoques diferentes para escribir un optimizador de mirilla, y me he decidido por un enfoque de back-end:

El codificador hace una llamada a unemit() Funciona cada vez que se genera una instrucción de máquina.emit(Instruction currentInstr) comprueba una tabla de optimizaciones de mirilla:Si la instrucción actual coincide con la cola de un patrón:Verifique las instrucciones emitidas previamente para el emparejamientoSi todas las instrucciones coinciden con el patrón, aplique la optimización, modificando el extremo final del almacén de códigoSi no se encuentra ninguna optimización, emita la instrucción como de costumbre.Enfoque de diseño actual

El método es bastante fácil, es la implementación con la que estoy teniendo problemas. En mi compilador, las instrucciones de la máquina se almacenan en unInstruction clase. Escribí unInstructionMatch la clase almacena expresiones regulares destinadas a coincidir con cada componente de una instrucción de máquina. Susequals(Instruction instr) método devuelvetrue si los patrones coinciden con alguna instrucción de la máquinainstr.

Sin embargo, no puedo lograr completamenteaplicar las reglas que tengo En primer lugar, siento que dado mi enfoque actual, terminaré con un lío de objetos innecesarios. Dado que una lista completa de números de optimizaciones de mirilla puede llegar a unos 400 patrones, esto se saldrá de control rápidamente. Además, no puedo obtener sustituciones más difíciles trabajando con este enfoque (consulte "Mi pregunta").

Enfoques alternativos

Un documento que he leído dobla las instrucciones previas en una cadena larga, usando expresiones regulares para hacer coincidir y sustituir, y convertir la cadena nuevamente a instrucciones de la máquina. Esto me pareció un mal enfoque, corríjame si me equivoco.

Ejemplo de patrones, sintaxis de patrones.
<code>x: JUMP x+1; x+1: JUMP y  -->  x: JUMP y
LOADL x; LOADL y; add     -->  LOADL x+y
LOADA d[r]; STOREI (n)    -->  STORE (n) d[r]
</code>

Tenga en cuenta que cada uno de estos patrones de ejemplo es solo una representación legible por humanos de la siguiente plantilla de instrucciones de la máquina:

<code>op_code register n d
</code>

(n suele indicar el número de palabras, yd un desplazamiento de dirección). La sintaxisx: <instr> Indica que la instrucción está almacenada en la dirección.x en el almacén de códigos.

Entonces, la instrucciónLOADL 17 Es equivalente a la instrucción completa de la máquina.5 0 0 17 cuando elLOADL opcode es 5 (n yr no se utilizan en esta instrucción)

Mi pregunta

Entonces, teniendo en cuenta esos antecedentes, mi pregunta es la siguiente: ¿Cómo puedo comparar y reemplazar los patrones cuando necesito incluir partes de instrucciones anteriores como variables en mi reemplazo? Por ejemplo, simplemente puedo reemplazar todas las instancias deLOADL 1; add con la instrucción de incremento de máquina: no necesito ninguna parte de las instrucciones anteriores para hacer esto. Pero no sé cómo usar efectivamente los valores 'x' e 'y' de mi segundo ejemplo en el patrón de sustitución.

editar: Debo mencionar que cada campo de unaInstruction La clase es solo un número entero (como es normal en las instrucciones de la máquina). Cualquier uso de 'x' o 'y' en la tabla de patrones es una variable para cualquier valor entero.

Respuestas a la pregunta(1)

Su respuesta a la pregunta