詞法分析實驗報告


一、實驗目的

  通過設計編制調試一個具體的詞法分析程序,加深對詞法分析原理的理解,並掌握在對程序設計語言源程序進行掃描過程中將其分解為各類單詞的詞法分析方法。編制一個讀單詞過程,從輸入的源程序中,識別出各個具有獨立意義的單詞,即基本保留字、標識符、常數、運算符、分隔符五大類,並依次輸出各個單詞的內部編碼及單詞符號自身值。

二、實驗內容和要求

實驗內容:用C語言對源程序進行詞法分析。通過輸入源程序從左到右對字符串進行掃描和分解,依次輸出各個單詞的內部編碼及單詞符號自身值;若遇到錯誤則顯示“Error”,然后跳過錯誤部分繼續顯示;同時進行標識符登記符號表的管理。

以下是實現詞法分析設計的主要工作:1)從源程序文件中讀入字符(2)統計行數和列數用於錯誤單詞的定位。(3)刪除空格類字符,包括回車、制表符空格。(4)按拼寫單詞,並用(內碼,屬性)二元式表示。(屬性值——token的機內表示)5)如果發現錯誤則報告出錯(6)根據需要是否填寫標識符表供以后各階段使用。

實驗要求:

1.待分析的簡單的詞法

1)保留字:if,else, for, while, do, int ,read, write,real,char 

2)純單分界符:+ * (){} 

3)雙分界符:> < = ! ,&&,||

2.實現功能:

1)在命令行中輸入源程序文件名(包括文件名路徑)

2)輸入目標文件名(包括文件名路徑)

3)調用所編詞法分析代碼將分析結果寫入目標文件代碼(編譯完成)

三、 實驗方法、步驟及結果測試

 1.      源程序名:詞法分析.zip   中源程序名:詞法分析.c

可執行程序名:詞法分析.exe

2.      原理分析及流程圖

主要算法:算法的基本任務是從輸入的字符串表示的源程序中識別出具有獨立意義的單詞符號,其基本思想是根據掃描到單詞符號的第一個字符的種類,拼出相應的單詞符號。

 存儲結構:順序存儲結構

關鍵函數的實現:通過掃描函數對輸入的字符串進行一一掃描

注:關鍵字作為特殊標識符處理,把它們預先安排在一張表格中(稱為關鍵字表),當掃描程序識別出標識符時,查關鍵字表。如能查到匹配的單詞,則該單詞為關鍵字,否則為一般標識符。

3.      流程圖:

4.主要程序段及其解釋: 

 

void scaner()

{
    /*共分為三大塊,分別是標示符、數字、符號,對應下面的 if else if 和 else */ 
    for(n=0;n<7;n++) 
        TOken[n]=0;//每次循環完就清零 
    ch=A[i];
    while(ch==' '||ch=='\n')//如果字符是空格或者回車,跳過 
    {
        i++;
        ch=A[i];
    }
    if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) //可能是標示符或者變量名 
    {
        m=0;
        while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))//找到一個變量名或者關鍵字,直到遇到空格為止 
        {
            TOken[m]=ch;m++;
            i++;ch=A[i];
        }
        TOken[m]='\0';//將識別出來的字符和已定義的標示符作比較, //因為定義的begin為1,if為2...... 
        if(strcmp(TOken,r1)==0){syn=1;}
        else if(strcmp(TOken,r2)==0){syn=2; }
        else if(strcmp(TOken,r3)==0){syn=3;} 
        else if(strcmp(TOken,r4)==0){syn=4;}
        else if(strcmp(TOken,r5)==0){syn=5;}
        else if(strcmp(TOken,r6)==0){syn=6;}
        else if(strcmp(TOken,r7)==0){syn=7;}
        else if(strcmp(r8,TOken)==0){syn=8;}
        else if(strcmp(r9,TOken)==0){syn=9;}
        else if(strcmp(r10,TOken)==0){syn=10;}
        else if(strcmp(r11,TOken)==0){syn=11;}
        else if(strcmp(r12,TOken)==0){syn=12;}
        else if(strcmp(r13,TOken)==0){syn=13;}
        else if(strcmp(r14,TOken)==0){syn=14;}
        else if(strcmp(r15,TOken)==0){syn=15;}
        else if(strcmp(r16,TOken)==0){syn=16;}
        else if(strcmp(r17,TOken)==0){syn=17;}
        else if(strcmp(r18,TOken)==0){syn=18;}
        else if(strcmp(r19,TOken)==0){syn=19;}
        else if(strcmp(r20,TOken)==0){syn=20;}
        else if(strcmp(r21,TOken)==0){syn=21;}
        else if(strcmp(r22,TOken)==0){syn=22;}
        else if(strcmp(r23,TOken)==0){syn=23;}
        else if(strcmp(r24,TOken)==0){syn=24;}
        else if(strcmp(r25,TOken)==0){syn=25;}
        else if(strcmp(r26,TOken)==0){syn=26;}
        else if(strcmp(r27,TOken)==0){syn=27;}
        else if(strcmp(r28,TOken)==0){syn=28;}
        else if(strcmp(r29,TOken)==0){syn=29;}
        else if(strcmp(r30,TOken)==0){syn=30;}
        else if(strcmp(r31,TOken)==0){syn=31;}
        else if(strcmp(r32,TOken)==0){syn=32;}
        else if(strcmp(r33,TOken)==0){syn=33;}
        else if(strcmp(r34,TOken)==0){syn=34;}
        else if(strcmp(r35,TOken)==0){syn=35;}
        else if(strcmp(r36,TOken)==0){syn=36;}
        else if(strcmp(r37,TOken)==0){syn=37;}
        else if(strcmp(r38,TOken)==0){syn=38;}
        else{syn=100;}    //變量名 
    }
    else if((ch>='0'&&ch<='9')) //數字 
    {
        sum=0;
        while((ch>='0'&&ch<='9'))
        {
            sum=sum*10+ch-'0';//顯示其數字sum 
            i++;
            ch=A[i];
        }
        syn=40;
    }
    else switch(ch) //其他字符 
    {
case'<':m=0;TOken[m]=ch;m++;
    i++;ch=A[i];
    if(ch=='=')//<>為22 
    {
        syn=41;
        TOken[m]=ch;m++;i++;
    }
    else
    {
        syn=46;
    }
    break;
case'>':m=0;TOken[m]=ch;m++;
    i++;ch=A[i];
    if(ch=='=')
    {
        syn=42;
        TOken[m]=ch;m++;i++;
    }
    else
    {
        syn=47;
    }
    break;
case':':m=0;TOken[m]=ch;m++;
    i++;ch=A[i];
    if(ch=='=')
    {
        syn=44;
        TOken[m]=ch;m++;i++;
    }
    else
    {
        syn=49;
    }
    break; 
case'@':syn=0;
    TOken[0]=ch;
    i++;
    break;
case'=':syn=48;
    TOken[0]=ch;
    i++;
    break; 
case'#':syn=50;
    TOken[0]=ch;
    i++;
    break;
case'+':syn=50;
    TOken[0]=ch;
    i++;
    break;
case'-':syn=51;
    TOken[0]=ch;
    i++;
    break;
case'*':syn=52;
    TOken[0]=ch;
    i++;
    break;
case'/':syn=53;
    TOken[0]=ch;
    i++;
    break; 
case'(':syn=54;
    TOken[0]=ch;
    i++;
    break;
case')':syn=55;
    TOken[0]=ch;
    i++;
    break;
case'{':syn=56;
    TOken[0]=ch;
    i++;
    break;
case'}':syn=57;
    TOken[0]=ch;
    i++;
    break; 
case';':syn=58;
    TOken[0]=ch;
    i++;
    break;
case'.':syn=59;
    TOken[0]=ch;
    i++;
    break;
case'\'':syn=60;
    TOken[0]=ch;
    i++;
    break;
case'\n':
    syn=-2;
    break;
default: syn=-1;
    break;
    }
}

 5. 運行結果及分析

 


免責聲明!

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



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