編譯原理 實驗1《詞法分析程序設計與實現》


1、定義目標語言的可用符號表

  1. 關鍵字:if,else,for,while,do,int,read,write,return
  2. 標識符:①標識符由字母、數字組成;②不能把c語言關鍵字作為標識符;③標識符對大小寫敏感;④首字符只能是字母,不能是數字。
  3. 常數:無符號整數值。
  4. 運算符:+、-、*、/、==、<=、>=、!=、=
  5. 界符:,、;、{、}、(、)

2、定義程序輸入輸出

  1. 程序輸入:依照c語言程序規則輸入,以txt文本形式存儲;
  2. 程序輸出:程序依照 類型 值 的形式每行一個進行輸出,例如 int int。

3、代碼

(1)頭文件 analysis.h

#include<stdio.h>
#include<ctype.h>
#include<string.h>
//下面定義保留字表,為簡化程序,使用字符指針數組保存所有保留字
//如果想增加保留字,可繼續添加,並修改保留字數目 keywordSum
#define keywordSum 9
char *keyword[keywordSum] = {"if","else","for","while","do","int","read","write","return"};
//下面定義純單分界符的首字符 
char singleword[50] = "!+-*(){};,:"; 
//下面定義雙分界符的首字符
char doubleword[10] = "><=!&|";
extern char Scanin[300], Scanout[300];
//用於接收輸人輸出文件名,在 test _ main.c 中定義
extern FILE *fin ,*fout; 		//用於指向輸入輸出文件的指針,在 test _ main.c 中定義
int TESTscan () 				//詞法分析函數
{
	char ch , token[40]; 		//ch 為每次讀人的字符,token 用於保存識別出的單詞
 	int es = 0,j,n; 			//es錯誤代碼,0表示沒有錯誤
	 							//j, n為臨時變量,控制組合單詞時的下標等
	printf("請輸人源程序文件名(包括路徑):");
	scanf("%s",Scanin);
	printf("請輸人詞法分析輸出文件名(包括路徑):");
 	scanf("%s",Scanout); 								
 	if(( fin = fopen(Scanin ,"r")) == NULL)				//判斷輸人文件名是否正確
 	{
		printf("\n打開詞法分析輸人文件出錯!\n"); 	
 		return (1);										//輸人文件出錯返回錯誤代碼1
 	}
 	if (( fout = fopen (Scanout ,"w")) == NULL )		//判斷輸出文件名是否正確
 	{
	 	printf("\n創建詞法分析輸出文件出錯!\n");
 		return(2);										//輸出文件出錯返回錯誤代碼2
 	}
 	ch = getc(fin);
 	while(ch != EOF)
 	{
 		while(ch == ' '|| ch == '\n' || ch == '\t') ch = getc(fin);
 		if(isalpha(ch))										//如果是字母則組合標識符
		{
			token[0] = ch; j = 1;
			ch = getc(fin);	
			while(isalnum(ch))							//如果是字符數字則組合標識符 
														//如果不是則標識符組合結束 
			{
				token[j++] = ch;						//組合的標識符保存在token中 
				ch = getc(fin);							//都下一個字符 
			}
			token[j] = '\0';							//標識符組合結束 
			
			//查保留字
			n = 0;
			while((n < keywordSum) && strcmp(token,keyword[n])) n++;
			if(n >= keywordSum)							//不是保留字,輸出標識符 
				fprintf(fout,"%s\t%s\n","ID",token);	//輸出標識符符號
			else										//是保留字,輸出保留字 
				fprintf(fout,"%s\t%s\n",token,token);	//輸出保留字符號 
		}else if(isdigit(ch))							//數組處理 
		{
			token[0] = ch; j = 1;
			ch = getc(fin);								//讀下一個字符 
			while(isdigit(ch))							//如果是數字則組合整數;如果不是則整數組合結束
			{
				token[j++] = ch;						//組合整數保存在token中
				ch = getc(fin);							//都下一個字符	
			}
			token[j] = '\0';							//整數組合結束
			fprintf(fout,"%s\t%s\n","NUM",token);		//輸出整數符號 
		}else if(strchr(singleword,ch) > 0)				//單分界符處理 
		{
			token[0] = ch; token[1] = '\0';				
			ch = getc(fin);								//讀下一個字符以便識別下一個單詞 
			fprintf(fout,"%s\t%s\n",token,token); 		//輸出單分界符符號 
		}else if(strchr(doubleword,ch) > 0)				//雙分界符處理 
		{
			token[0] = ch;
			ch = getc(fin);								//讀下一個字符判斷是否為雙分界符
			if(ch == '=')								//如果是=,組合雙分界符  != == >= <= 
			{
				token[1] = ch; token[2] = '\0';			//組合雙分界符結束 
				ch = getc(fin);							//讀下一個符號以便識別下一個單詞 
			} else if(ch == '&')						//判斷是否是&& 
			{
				token[1] = ch; token[2] = '\0';
				ch = getc(fin);
			}
			else if(ch == '|')							//判斷是否是|| 
			{
				token[1] = ch; token[2] = '\0';
				ch = getc(fin);
			} else
				token[1] = '\0';
			
			fprintf(fout,"%s\t%s\n",token,token);		//輸出單或雙分界符 
		}else if(ch == '/')								//注釋處理 
		{
			ch = getc(fin);								//讀下一個字符 
			if(ch == '*')								//如果是*,則開始處理注釋 
			{
				char ch1;
				ch1 = getc(fin);						//讀下一個字符 
				do
				{
					ch = ch1; ch1 = getc(fin);			//刪除注釋 
				} while((ch != '*' || ch1 != '/')&&ch1 != EOF);
														//直到遇到注釋結束符 * / 或文件尾 
				ch = getc(fin); 						//讀下一個字符以便識別下一個單詞 
			}else										//不是*則處理單分界符 
			{
				token[0] = '/'; token[1] = '\0';
				fprintf(fout,"%s\t%s\n",token,token);	//輸出單分界符 
			}
		}else											//錯誤處理 
		{
			token[0] = ch; token[1] = '\0';
			ch = getc(fin);								//讀下一個符號以便識別下一個單詞 
			es = 3;										//設置錯誤代碼 
			fprintf(fout,"%s\t%s\n","ERROR",token);		//輸出錯誤符號 
		}
	}
	fclose(fin);									//關閉輸入輸出文件 
	fclose(fout);
	return(es);										//返回主程序 
}

(2)測試 main.cpp

#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include"analysis.h"
extern int TESTscan();
char Scanin[300],Scanout[300];			//用於接收輸入輸出文件名
FILE *fin,*fout;						//用於指向輸入輸出文件的指針
int main() {
	int es = 0;
	es = TESTscan();
	if(es > 0) 
		printf("詞法分析有錯,編譯停止!");
	else
		printf("詞法分析成功!\n"); 
} 

4、測試

(1)輸入文件 test.txt

在這里插入圖片描述

(2)運行

在這里插入圖片描述

(3)輸入文件 result.txt

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM