天天看點

編譯原理學習(一)詞法分析器

一. 實驗目的

  1. 了解詞法分析器的工作原理。
  2. 掌握利用狀态轉換圖設計詞法分析器的基本方法。
  3. 實作Micro語言的詞法分析程式

二. 實驗内容

根據給出的Micro語言的定義,設計并實作它的的詞法分析器,實作源程式的輸入、 預處理和詞法分析,最後以編譯程式需要的内部表示形式(二進制組)将識别的 單詞符号輸出。 利用狀态轉換圖設計Micro語言的詞法規則。 用C語言實作該語言詞法分析程式

三. 實驗步驟

  1. 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++語言的用途的了解。

繼續閱讀