Experimento 2 "Diseño e implementación de programas de análisis léxico" (versión en lenguaje C)

texto

detalles de la misión

Las tareas de este nivel: profundizar la comprensión del proceso de trabajo del analizador léxico; fortalecer el dominio del método de análisis léxico; ser capaz de utilizar un lenguaje de programación para implementar un programa de análisis léxico simple; analizar.

información relacionada

Para completar la tarea de este nivel, debe dominar: Diseño e implementación de programas de análisis léxico.

Conocimientos básicos de análisis léxico

El analizador léxico (Lexer para abreviar) es responsable de escanear y descomponer el programa fuente carácter por carácter de izquierda a derecha, e identificar los símbolos de palabras uno por uno de acuerdo con las reglas léxicas del idioma.

Por lo tanto, un analizador léxico debe tener las siguientes funciones:

  • Escanea el flujo de caracteres que componen el programa fuente de izquierda a derecha
  • Reconocer palabras con significado léxico.
  • Devolver registros de palabras o mensajes de error léxico

De lo anterior se puede ver que un eslabón importante en el análisis léxico es identificar el tipo de símbolos de palabras Para facilitar el análisis gramatical, los símbolos de palabras generalmente se dividen en cinco categorías.

  1. Los identificadores
    se utilizan para nombrar variables, arreglos, funciones, procedimientos, etiquetas, etc. que aparecen en un programa, generalmente una cadena alfanumérica que comienza con una letra, como longitud, siguiente, etc.

  2. Las palabras básicas
    también pueden ser palabras clave o palabras reservadas. Tales como if, while, for, do, goto, etc. Tienen forma de identificadores, pero no están definidos por el usuario sino por el lenguaje, y su significado es por convención. Está estipulado en la mayoría de los idiomas que no se pueden usar como identificadores o prefijos de identificadores, es decir, los usuarios no pueden usarlos para definir los nombres que usan los usuarios, por lo que los llamamos palabras reservadas, como Pascal y C. Pero también existen lenguajes que permiten utilizar palabras básicas como identificadores o prefijos de identificadores, como Fortran.

  3. Las constantes
    incluyen varios tipos de constantes, como enteros, reales, caracteres, booleanos, etc. Tales como: 5, 3.1415926, a, TRUE, etc. son todas constantes.

  4. Operadores Operadores
    aritméticos +, -, ×, ÷; operadores relacionales <,<=,>,>=,==,!= y operadores lógicos &&, (), || o !, etc.

  5. Delimitadores como delimitadores de un solo
    carácter como , ; y delimitadores de dos caracteres como /,/,// y caracteres en blanco, etc.

Después del análisis léxico, las palabras reconocidas deben estar en alguna representación intermedia a la que se pueda hacer referencia fácilmente para las etapas posteriores de compilación. Por lo general, una palabra se representa mediante un binario:
(categoría de palabra, atributo de palabra)
Entre ellos, el primer elemento se utiliza para distinguir la categoría a la que pertenece la palabra y se representa mediante un código entero. El segundo elemento se utiliza para distinguir qué palabra símbolo en la categoría, es decir, el valor de la palabra símbolo.

Procedimiento experimental

De las funciones que debe tener un analizador léxico, nuestro programa tiene los siguientes requisitos:

  • Hay una definición clara de las reglas de formación de palabras para las palabras;
  • El programa de análisis escrito puede identificar correctamente los símbolos de palabras en el programa fuente;
  • Las palabras reconocidas se almacenan en la tabla de símbolos en forma de <código de categoría, valor>, y la tabla de símbolos está diseñada y mantenida adecuadamente;
  • Para los errores léxicos en el programa fuente, se puede realizar un manejo de errores simple y se pueden proporcionar mensajes de error simples para garantizar la finalización sin problemas del análisis léxico de todo el programa fuente;

requisitos de programación

De acuerdo con el mensaje, después de agregar el programa de reconocimiento de identificadores de código, caracteres numéricos y otros símbolos de caracteres en el editor de la derecha, haga clic en la evaluación para ejecutar el programa y el sistema comparará automáticamente los resultados.

introducción a la prueba

La plataforma prueba el código que escribes:

Entrada de prueba:

    using namespace std;
    int main()
    {
        int year;
        cout << "hello" << endl;
        return 0;
    }
    #  

¡Comienza tu búsqueda y buena suerte!

respuesta de laboratorio

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
char prog[80], token[20];
char ch;
int syn, p, m = 0, n, row, sum = 0;
const char* rwtab[8] = { "if","int","for","while","do","return","break","continue" };
const char* rwtab1[8] = { "main","a","b","c","d","e","f","g" };

void scaner()
{
	/*
		共分为三大块,分别是标示符、数字、符号,对应下面的 if   else if  和 else
	*/
	for (n = 0; n < 8; n++) token[n] = NULL;
	ch = prog[p++];
	while (ch == ' ')
	{
		ch = prog[p];
		p++;
	}
	if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
		m=0;
		while(1){
			if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
				token[m++]=ch;
				ch=prog[p++];

			}else{
				p--;
				break;
			}
		}
		token[m]='\0';
		syn=0;
		for(n=0;n<8;n++){
			if (strcmp(token, rwtab1[n]) == 0)
			{
				syn = 2;
				break;
			}
			else if (strcmp(token, rwtab[n]) == 0) {
				syn = 1;
				break;
			}
		}	
		if(!syn)syn=2;		

	}else if ((ch >= '0' && ch <= '9')) {
		syn=3;
		sum=ch-'0';
	}
	else switch (ch)   //其他字符 
	{
		case'<':m = 0; token[m++] = ch;
				ch = prog[p++];
				if (ch == '>')
				{
					syn = 4;
					token[m++] = ch;
				}
				else if (ch == '=')
				{
					syn = 4;
					token[m++] = ch;
				}
					else
					{
						syn = 4;
						p--;
					}
					break;
			case'>':m = 0; token[m++] = ch;
					ch = prog[p++];
					if (ch == '=')
					{
						syn = 4;
						token[m++] = ch;
					}
					else
					{
						syn = 4;
						p--;
					}
					break;
			case':':m = 0; token[m++] = ch;
					ch = prog[p++];
					if (ch == '=')
					{
						syn = 4;
						token[m++] = ch;
					}
					else
					{
						syn = 4;
						p--;
					}
					break;
			case'*':syn = 4; token[0] = ch; break;
			case'/':syn = 4; token[0] = ch; break;
			case'+':syn = 4; token[0] = ch; break;
			case'-':syn = 4; token[0] = ch; break;
			case'=':syn = 4; token[0] = ch; break;
			case';':syn = 5; token[0] = ch; break;
			case',':syn = 5; token[0] = ch; break;
			case'(':syn = 5; token[0] = ch; break;
			case')':syn = 5; token[0] = ch; break;
			case'{':syn = 5; token[0] = ch; break;
			case'}':syn = 5; token[0] = ch; break;
			case'#':syn = 0; token[0] = ch; break;
			case'\n':syn = -2; break;
			default: syn = -1; break;
	}

}
	



int main()
{
	p = 0;
	row = 1;
	cout << "Please input string:" << endl;
	do
	{
	cin.get(ch);
	prog[p++] = ch;
	} while (ch != '#');
	p=0;
    do{
      scaner();
	  //cout<<syn<<endl;
	  //cout<<syn<<endl;
      switch (syn)
      {
		case 0: break;
		case 3: cout << "(" << syn << "," << sum << ")" << endl; break;
		case -1: cout << "Error in row " << row << "!" << endl; break;
		case -2: row = row++; break;
		default: cout << "(" << syn << "," << token << ")" << endl; break;
      }
	  //cout<<row<<endl;
	  if(syn==-2)row++;
    } while (syn != 0); 
}

Epílogo


"Si estás indeciso, puedes preguntarle a la brisa primaveral, y si la brisa primaveral no habla, seguirás a tu corazón" significa: si tienes dudas sobre algo, pregúntale a la brisa primaveral cómo hacerlo. . "Si no está decidido, puede preguntarle a la brisa primaveral. Si la brisa primaveral no habla, seguirá su corazón". La oración proviene del "Jianlai" escrito por el escritor de Internet "Fenghuo Opera Princes". El texto original es: "Si estás indeciso, puedes preguntarle a la brisa primaveral. Sigue tu corazón".

inserte la descripción de la imagen aquí


Supongo que te gusta

Origin blog.csdn.net/weixin_46627433/article/details/123852643
Recomendado
Clasificación