一. 實驗目的
- 了解詞法分析器的工作原理。
- 掌握利用狀态轉換圖設計詞法分析器的基本方法。
- 實作Micro語言的詞法分析程式
二. 實驗内容
根據給出的Micro語言的定義,設計并實作它的的詞法分析器,實作源程式的輸入、 預處理和詞法分析,最後以編譯程式需要的内部表示形式(二進制組)将識别的 單詞符号輸出。 利用狀态轉換圖設計Micro語言的詞法規則。 用C語言實作該語言詞法分析程式
三. 實驗步驟
-
Micro語言的定義
僅有的資料類型是整型INT。
所有的辨別符采用顯式聲明,且長度不超過32個字元。辨別符必須以字母開頭并由字母、數字和下劃線組成。
整型常量由一串數字組成。
注釋由“–”開始,并在目前行尾結束。
語句類型為:
指派語句:
ID := Expression;
Expression是由辨別符、文字常量、+ - * / 運算符組成的中綴表達式結構,其中允許含有括号。
輸入輸出語句:
read( List of IDs);
write(List of Expressions);
begin、end、read、write、INT都是保留字。
每條語句以分号(;)結束。程式體由begin和end界定。
詞法記号不能跨行。
編譯原理學習(一)詞法分析器 編譯原理學習(一)詞法分析器
四、代碼
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *key_word[] = { "int", "begin", "end", "read", "write" };
int i = , j = , k = , t = ; // 搜尋訓示器
#define BUFFERSIZE 1000
char ch; // 存放最新讀入的源程式字元
char str_token[]; // 存放構成單詞符号的字元
char *char_form[]; // 字元表
char *int_form[]; // 常數表
char form[BUFFERSIZE];
int q = ;
int temp;
FILE *fp;
// 常用語句的宏定義
#define GET_CHAR ch = form[k]; k++; // 将下一個字元讀到ch,搜尋訓示器 前移一個字元位置
#define GET_BC while(ch == ""){ GET_CHAR;} // 檢查ch字元是否為空白。是的話調用get_char
#define CONCAT str_token[i] = ch; i++; // 連結字元
//判斷是否為字母
int isLetter()
{
if (((ch <= 'z') && (ch >= 'a')) || ((ch <= 'Z') && (ch >= 'A')))
return ();
else
return ();
}
//判斷是否為數字
int isDigit()
{
if ((ch >= '0') && (ch <= '9'))
return ();
else
return ();
}
//判斷是否為關鍵字
int reserve()
{
int q = ;
for (q = ; q<; q++){
if (strcmp(str_token, key_word[q]) == )
return q;
}
return -;
}
//函數回調
void retract() //将搜尋訓示器回調一個字元位置,将ch置為空白字元
{
k--;
ch = NULL;
}
//将strToken中的辨別符插入符号表,傳回符号表指針
char *insertId()
{
char_form[j] = str_token;
j++;
return char_form[];
}
//将strToken中的常數插入常數表,傳回常數表指針
char *inserConst()
{
int_form[t] = str_token;
t++;
return int_form[];
}
//詞法分析器的構造
int code;
void scanner()
{
for (i = ; i<; i++)
str_token[i] = NULL;
i = ;
GET_CHAR;
GET_BC;
printf("這是一個 ");
if (isLetter()){
while (isLetter() || isDigit()){
concat();
GET_CHAR;
}
retract();
code = reserve();
switch (code){
case -:
printf("字元串 %s\n", &str_token);
break;
default:
printf("關鍵字 %s\n", &str_token);
break;
}
}
else if (isDigit()){
while (isDigit()){
concat();
GET_CHAR;
}
retract();
printf("運算符 %s\n", &str_token);
}
else if (ch == '='){
printf("運算符 =%s\n", &str_token);
}
else if (ch == '+'){
printf("運算符 +%s\n", &str_token);
}
else if (ch == '-'){
printf("運算符 -%s\n", &str_token);
}
else if (ch == ';'){
printf("界符 ;%s\n", &str_token);
}
else if (ch == '('){
printf("界符 (%s\n", &str_token);
}
else if (ch == ')'){
printf("界符 )%s\n", &str_token);
}
}
void main() {
int n = ;
fp = fopen("C:\\Users\\MySHworks\\Desktop\\test.txt", "r");
while(fgets(form, , fp) != NULL){
k = ;
while (form[k] != '\0')
scanner();
}
system("pause");
fclose(fp);
}
五、心得
詞法分析的主要任 務是:根據構造的狀态轉換圖,從左到右逐個字元地対源程式進行掃描,識别的最小文法機關——符号或單詞,如變量辨別符,關鍵字,常量,運算符,界符等。然後将提取出的辨別符以内碼的形式表示,即用int類型的數字來表示其類型和在display表中的位置,而無須保留原來辨別符本身的字元串,這不僅節省了記憶體空間,也有利于下一階段的分析工作。通過此次實驗,讓我了解到如何設計、編制并調試詞法分析程式,加深對詞法分析原理的了解;熟悉了構造詞法分析程式的手工方式的相關原理,使用某種進階語言(例如C++語言)直接編寫此法分析程式。另外,也讓我重新熟悉了C++語言的相關内容,加深了對C++語言的用途的了解。