Análisis sintáctico y programación de análisis semántico de sentencias de bucle.
1 Trabajo del curso--------------------------------(2)
1 Descripción del problema----------------------------------------------------- ( 3)
2 Sintaxis y descripción de sintaxis de atributos---------------------------(3)
2.1 Sintaxis de la instrucción del bucle while-do---------------------(3)
2.2 Estructura del bucle while-do Traducción de declaraciones-----------------(3)
3 Análisis sintáctico y descripción del formulario de código intermedio------------- - -----(4)
3.1 Método de análisis sintáctico------------------------------ ---- (4)
3.2 Descripción del formulario de código intermedio----------------------- ----(4)
4 Breve análisis y diseño del esquema--------------------------(5)
4.1 Análisis léxico-- --------------------------------(5)
4.2 Traductor de descenso recursivo diseño-- -------------------(5)
4.3 Traducción guiada por gramática------------- -- ----------------(5)
5 Descripción detallada del algoritmo------------------ ------------(6)
5.1 Sintaxis-------------------------- ------------- (6)
5.2 Comprobación de errores--------------------------------- ----- --------------- (6)
6 Métodos de prueba y resultados de prueba------------ -- ----- --------(9)
6.1 Método de prueba------------------------ -------- -----(9)
6.2 Resultados de la prueba------------------------ -------- --(10)
7 Características, deficiencias, ganancias y experiencias del diseño----------------- (10)
7.1 Características del diseño-------------------------------- (10)
7.2 Desventajas, ganancias y experiencia------------------------------ (11)
8 Referencias ---------- -----------------------(11)
Plan de estudios Libro de tareas de diseño
Título: Programación de análisis de sintaxis y semántica de declaraciones de bucle (método de descenso recursivo)
1. Propósito
Profundizar en la comprensión de los principios de Análisis sintáctico y semántico a través del diseño, programación y depuración de programas de análisis sintáctico y semántico.
2. Contenido y requisitos de enseñanza
WHILE〈Expresión booleana〉DO〈Declaración de tarea〉
Entre ellos
(1) 29 ~ El estudiante No. 32 eligió el método de descenso recursivo, LL (1), el método de análisis de prioridad del operador (o método de prioridad simple) y el método LR para completar las tareas anteriores, y el código intermedio eligió la forma de cuaternión.
(2) Como en la pregunta 1, escriba una gramática que cumpla con los requisitos del método analítico, dé la idea del método analítico y complete la programación analítica.
(3) Después de compilar el programa de análisis, diseñe varios casos de uso, pruebe y apruebe el programa de análisis diseñado en la computadora.
3. El contenido del informe de diseño del curso debe incluir:
1. Título del diseño, clase, número de estudiante, nombre, fecha de finalización; Dar Descripción de métodos de análisis sintáctico y formas de códigos intermedios, diseño de gramática y gramática de atributos o métodos de análisis léxico
3.
4. Breve análisis y diseño del esquema;
5. Descripción detallada del algoritmo
6. 7. Proporcionar los métodos de prueba del software y los resultados de las pruebas;
8. Evaluación, cosecha y lecciones aprendidas del diseño.
4. Horario:
Semana 17, mañanas de las semanas 1-4, todo el día viernes
Firma del instructor: año, mes y día
p>
Firma del jefe de departamento (o docente a cargo): año, mes, día
1 Descripción del problema
Diseñar un WHILE (expresión booleana) DO (declaración de tarea) ) Programas de análisis léxico y sintáctico y semántico de sentencias en bucle. Al analizar la sintaxis y la semántica del programa, se selecciona el método de descenso recursivo para la sintaxis, y la sintaxis se utiliza para guiar la traducción y salida de los cuaterniones de código intermedio.
2 Sintaxis y descripción de sintaxis de atributos.
2.1 La sintaxis de la instrucción del bucle while-do
La fórmula generada es S--gt; while E do A. Para facilitar la traducción guiada por la sintaxis, se reescribe de la siguiente manera:
La gramática G(s) es la siguiente:
S--gt.c= mientras E do G)
G--gt.c= R
R--gt; dTe|d
T--gt |-|*|/
E--gt; >
F- -gt; gt; |==|lt;
2.2 Traducción estructural de la declaración del bucle whlie-do:
3. Descripción del método de análisis de sintaxis e intermedio forma de código
3.1 Método de análisis gramatical
La idea de implementación del método de descenso recursivo es diseñar una subrutina recursiva correspondiente para cada símbolo no terminal en la gramática. consta de un conjunto de subrutinas de este tipo.
La ventaja es que es simple e intuitivo, fácil de construir y puede ser implementado por muchos sistemas de compilación.
La desventaja es que tiene altos requisitos gramaticales y debido a la gran cantidad de llamadas recursivas afecta el rendimiento del analizador.
La sintaxis se puede expresar como
E→T│E T
T→. F│T*F
F→i│( E)
La gramática de este idioma se puede representar mediante un diagrama de sintaxis, como se muestra en la figura:
E
T
F
3.2 Descripción de la forma del código intermedio
El código intermedio se genera en forma de cuaternión La forma de cuaternión es una estructura de registro con cuatro campos, llamados oop, arg1, arg2 y resultado.
La salida del cuaternión de la declaración while alt; b do a=a b es la siguiente:
100 ( lt; , a , b , 102 )
101 ( j , _ , _ , 105 )
102 ( , a , b , n )
103 ( = , n , _ , a )
104 ( j , _ , _ , 100 )
104 (j, _, _, 100)
105
4. Breve análisis y diseño del esquema
4.1 Análisis léxico
La tarea del programa de análisis léxico es escanear el programa fuente palabra por palabra de izquierda a derecha, generar símbolos de palabras uno por uno y convertir el programa fuente (cadena) en un programa intermedio de símbolos de palabras. Los errores comprobados mediante análisis léxico tienen como objetivo principal seleccionar símbolos ilegales que aparecen en el programa fuente. Los llamados símbolos ilegales se refieren a símbolos cuyo uso no está permitido en los lenguajes de programación, como los errores tipográficos en oraciones naturales.
4.2 Diseño de traductor descendiente recursivo
1: Construya un procedimiento de función para cada A no terminal, establezca un parámetro formal para cada atributo heredado de A y el valor de retorno del La función es una propiedad compuesta de A. El procedimiento de función correspondiente a A establece una variable local para cada atributo de cada símbolo de sintaxis que aparece en la fórmula de generación de A, y el procedimiento de función correspondiente al no terminal A decide qué candidato de generación usar en función del símbolo ingresado actualmente.
2: El código de programa correspondiente a cada generador realiza las siguientes operaciones sobre símbolos de parte del discurso, no terminadores y acciones semánticas en orden de izquierda a derecha.
(1) Para un terminador X con un atributo compuesto x, almacene el valor de x en el conjunto de variables de
(2) Para cada símbolo B no terminal, genere la declaración de asignación c=B(b1, b2,..., bk)
(3) Para acciones semánticas, El código de acción se copia en el analizador, reemplazando cada referencia a la propiedad correspondiente con la variable que representa la propiedad.
4.3 Traducción guiada por sintaxis
Durante el proceso de análisis de sintaxis, a medida que el análisis avanza gradualmente, la traducción se basará en la subrutina semántica (o la subrutina semántica descrita por las reglas semánticas). ) correspondiente a cada acción semántica). Cada símbolo de una gramática de atributos tiene atributos, por lo que cuando coloca cada símbolo en la pila, debe colocarlo en la pila junto con los atributos, de modo que el símbolo de la pila esté formado por el símbolo de sintaxis y el dominio que contiene los atributos del símbolo. Dado que los tipos de atributos son diferentes, el contenido del campo de atributo debe determinarse según el tipo de atributo. Algunas propiedades pueden almacenar el valor de la propiedad directamente, mientras que otras pueden almacenar punteros al valor de la propiedad. Para los atributos compuestos, el dominio del atributo no almacena el valor del atributo, sino que almacena un puntero a la celda donde se encuentra el valor del atributo. Para propiedades heredadas, el dominio de propiedad almacena el valor de la propiedad directamente. Los campos de propiedad de las propiedades heredadas están vacíos cuando se agregan por primera vez a la pila, pero en algún momento antes de que ese símbolo de la pila se convierta en el símbolo superior de la pila, deben recibir el valor de propiedad correspondiente, es decir, cuando se convierten en el símbolo superior de la pila. pila, la herencia El dominio del atributo debe tener un valor.
5 Descripción detallada del algoritmo
5.1 Sintaxis
/*
Sintaxis G(s)
s- -gt; WEDG
G--gt; c=R
R--gt; dTe|d
T -gt |-|*| /|E-- gt; aFb
F--gt; gt;==|lt
*/
5.2 Comprobación de errores
Obtenga Walt según el método de descenso recursivo; después de bDa=a b, el orden de ejecución del programa debe ser S()W()EF()D()G()R()T()
S()
S()
void S()
{
printf("d\tS- -gt; WEDG\n", total); total;
W();
E();
}
W()
void W()
{
if(ch!='W')
{
printf("¡¡Hay caracteres ilegales c, presione enter para regresar!!!" , ch
getchar()
getchar()
;salir(1);
}
}
E()
void E()
{
ch=a[ i1];
if( ch!='a')
{
printf( "Hay caracteres ilegales c c por favor presione enter para regresar!"
getchar()
getchar()
exit(1) ;
p>
}
printf("d\tE--gt; aFb\n", total
F(
}
F()
void F()
{
int i;
ch=a[i1];
i=i1 1;
if(a[i]! = 'b')
{
printf("¡¡Hay caracteres ilegales c, por favor presione enter para regresar!!" , a[i]); getchar();
getchar();
salir(1);
}
cambiar(ch)
{
caso 'gt;':
printf("d\tF-- gt;gt;\n", total;
<); p> descanso;caso '==':
printf("d\tF--gt; ==\n", total
<); p> descanso;Predeterminado.
printf("d\tF--gt;lt;\n", total
descanso
}
D();
G();
}
D()
nulo D()
{
i1;
ch=a[ i1]
if(ch!='D')
{
printf("¡Hay un carácter ilegal c, por favor presione enter para regresar!", ch
getchar()
getchar(); ;
salir(1);}
ch=a[ i1];
}
G()
void G()
{
int i=i1 1.
if(ch!='c'amp;amp;a[i ]! = '=')
{
printf("¡¡Hay caracteres ilegales c c por favor presione enter para regresar!!!"), ch, a[i]); /p>
getchar();
getchar();
salir(1); "d\tG--gt;c=R\n", total
R()
}
R()<; /p>
void R()
{
int i
i=i1 1
i1=i1; 2;
ch=a[i1];
if(a[i]!='='amp; amp;ch!='d')
{
printf("Hay caracteres ilegales c c¡¡Por favor presione Enter para regresar!!", a[i], ch
getchar();
getchar();
salir(1
}
más
{
if((a[i1 1]==' ')||(a[i1 1]=='-')||(a [i1 1]=='*')||(a[i1 1] = ='/'))
{
printf("d\tR--gt; dTe\n", total
T (
}
else
{
printf("d\tR--gt;dTe\n", total ); ; total
W();
E(); /p>
}
T()
void T()
{
ch=a[ i1] ;
switch(ch)
{
case ' ':
printf("d\tT--gt; \n " , total);
otal;
descanso;
caso '-':
caso '*':
printf("d\tT-- gt; -\n", total); total;
descanso;
caso '*':
printf("d\tT--gt; *\n", total); total;
descanso;
Valor predeterminado:
printf("d\tT--gt;/\n" , total); total
descanso
}
ch='#'; 6 Métodos de prueba y resultados de prueba
6.1 Métodos de prueba
En el entorno C, diseñe varios casos de uso representativos y pruébelos, por ejemplo, declaración de entrada Walt; d representa hacer y w representa mientras). Si los resultados que obtiene no son los esperados, entonces hay algún problema con el programa. Si hay un problema, realice una depuración de un solo paso para descubrir los problemas lógicos en el programa.
6.2 Resultados de las pruebas
Los resultados de las pruebas son los siguientes:
7 Características del diseño, deficiencias, experiencias y lecciones aprendidas
7.1 Diseño características
Este diseño utiliza el método de descenso recursivo para analizar la sintaxis y la semántica de la instrucción de bucle while-do de entrada y genera cuaterniones. Por lo tanto, este programa encarna plenamente la idea de descenso recursivo.
7.2 Deficiencias, ganancias y experiencias de diseño
Las deficiencias de este diseño son principalmente que no generalicé el programa en cuaterniones que realizan el análisis léxico del código de entrada automático del usuario para la salida. el programa solo puede implementar el análisis Walt; bDa=a b# y la salida de cuaterniones, y dado que la pila que diseñé solo puede almacenar un carácter a la vez, solo puedo usar D W para representar do W respectivamente. Solo puedo usar D W para representar do while respectivamente; y no estoy muy familiarizado con la traducción guiada por gramática, por lo que nunca he podido usar un programa para implementar la traducción guiada por gramática para generar cuaterniones, por lo que escribí directamente el cuaternión basado en mi propio número.
El diseño de este curso consolidó mi comprensión del descenso recursivo, me brindó una comprensión más profunda del ciclo WHILE-DO y mejoró mi capacidad práctica.
8 referencias de diseño de cursos
1 Principios de compilación de Zhang Xing'er (segunda edición) Tsinghua University Press
2 Principios de compilación de He Yanxiang, Universidad de Huazhong de Prensa de ciencia y tecnología
3 Chen Huowang "Principios de compilación del lenguaje de programación" (tercera edición) Prensa de la industria de defensa nacional
Formulario de evaluación de logros de diseño de cursos de pregrado