En esto, cubriremos la descripción general del analizador de precedencia de operadores y nos centraremos principalmente en el papel del analizador de precedencia de operadores. Y también cubrirá el algoritmo para la construcción de la función de precedencia y finalmente discutirá la recuperación de errores en el análisis de precedencia de operadores. Discutámoslo uno por uno.
Introducción:
analizador de precedencia de operadores construido para la gramática de precedencia de operadores. La gramática de precedencia de operadores es una gramática que no contiene producciones épsilon y no contiene dos no terminales adyacentes en RHS de ninguna producción. La gramática de precedencia de operadores se proporciona con reglas de precedencia. La gramática de precedencia de operadores puede ser ambigua o inequívoca.
Algoritmo del analizador de precedencia de operadores:
1. If the front of input $ and top of stack both have $, it's done else 2. compare front of input b with ⋗ if b! = '⋗' then push b scan the next input symbol 3. if b == '⋗' then pop till ⋖ and store it in a string S pop ⋖ also reduce the poped string if (top of stack) ⋖ (front of input) then push ⋖ S if (top of stack) ⋗ (front of input) then push S and goto 3
Diagrama de operador de componentes:
Ejemplo:
tomemos un ejemplo para comprender el papel de la precedencia del operador de la siguiente manera.
E-> E+T/T T-> T*V/V V->a/b/c/d string= "a+b*c*d"
Implementación del algoritmo anterior para la string «a+b*c*d» de la siguiente manera.
Pila | Aporte | parte superior de la pila | Entrada actual | Acción |
---|---|---|---|---|
ps | a+b*c*d$ | ps | a | cambiar un |
$a | +b*c*d$ | A | + | reducir usando A->a |
$V | +b*c*d$ | V | + | reducir usando T->V |
$T | +b*c*d$ | T | + | reducir usando E->T |
$E | +b*c*d$ | mi | + | cambio + |
$E+ | b*c*d$ | b | * | reducir usando V->b |
$E+V | b*c*d$ | V | * | reducir usando T->V |
$E+T | *c*d$ | T | * | cambio * |
$E+T* | c*d$ | * | C | cambio c |
$E+T*c | *d$ | C | * | reducir usando V->c |
$E+T*V | *d$ | V | * | reducir usando T->T*V |
$E+T | *d$ | T | * | cambio * |
$E+T* | d$ | * | d | cambio d |
$E+T*d | ps | d | ps | reducir usando V->d |
$E+T*V | ps | V | ps | reducir usando T->T*v |
$E+T | ps | T | ps | reducir usando E->E+T |
$T | ps | mi | ps | aceptar |
Algoritmo para la construcción de la función de precedencia:
- Genere una función Xa para cada terminal gramatical a y para el final del símbolo de string.
- Divida el símbolo en grupos de modo que Xa e Yb sean los mismos grupos si a ≐ b.
- Genere un gráfico dirigido cuyos Nodes estén en los grupos, para cada símbolo a y b, coloque una arista del grupo de Yb al grupo de Xa si a ⋖ b, de lo contrario, si a ⋗ b coloque una arista del grupo de Xa a la de Yb.
- Si el gráfico construido tiene un ciclo, entonces no existen funciones de procedimiento. Cuando no hay ciclos, recopile la longitud de los caminos más largos de los grupos de Xa y yb respectivamente.
Ejemplo:
tomemos un ejemplo para comprender la construcción de la función de precedencia de la siguiente manera.
E -> E + E/E * E/( E )/id
Aquí verá la tabla de relaciones de precedencia de operadores y el diagrama gráfico de relaciones de precedencia. Echemos un vistazo.
Como podemos ver que no hay ciclo, no hay ciclo en el gráfico, podemos hacer esta tabla de funciones de la siguiente manera.
Función de representación de columnas:
Las columnas representan la función Ya y las filas representan la función Xa.
Se calcula tomando la ruta más larga de Xid a X$y de Yid a Y$.
fid -> g* -> f+ ->g+ -> f$ gid -> f* -> g* ->f+ -> g+ ->f$
- La desventaja de la tabla de relaciones de precedencia de operadores es que si hay ‘n’ números de símbolos, entonces necesitamos una tabla de n*n para almacenarlos. Por otro lado, al usar la tabla de funciones del operador, para acomodar un número n de símbolos, necesitamos una tabla de 2*n. La gramática de precedencia de operadores no puede decidir el menos unario (el analizador léxico debe manejar el menos unario).
- La ventaja de usar la gramática de precedencia de operadores es que es simple y lo suficientemente poderosa para la expresión en lenguajes de programación.
Recuperación de errores en el análisis de precedencia de operadores:
- Casos de error:
1. No se mantiene ninguna relación entre el terminal en la parte superior de la pila y el siguiente símbolo de entrada.
2. Se encuentra un mango (paso de reducción), pero no hay producción con este mango como lado derecho.
- Recuperación de errores:
1. Cada entrada vacía se llena con un puntero a una rutina de error.
2. Decide que el asa reventada «se parece» a qué lado derecho. Y trata de recuperarse de esa situación.
- Manejo de cambio/reducción de errores:
para solucionar este tipo de errores, debemos modificar lo siguiente.
1. Pila
2 . Entrada
3. o Ambos
Publicación traducida automáticamente
Artículo escrito por tanushree7252 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA