程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 深入淺出編譯原理-4-一個簡單詞法分析器的C語言實現

深入淺出編譯原理-4-一個簡單詞法分析器的C語言實現

編輯:關於C語言

引言

光說不練,假把式。

此小節來做一個實驗,用c語言自己實現一個簡單的詞法分析器,來加深對詞法分析的理解。感興趣的就自己分析一下源碼吧,挺簡單的,就沒畫流程圖,請見諒。閒言少敘,我們開始吧。

 

4.1實驗描述

例如:對源程序:

begin x:=9: if x>9 then x:=2*x+1/3; end #


的源文件,經過詞法分析後輸出如下序列:

<1,begin><10,x><18,:=><11,9><26,;><2,if>……

 

4.1.1待分析的簡單的詞法

(1)關鍵字:

 begin  if  then  while  do  end

所有的關鍵字都是小寫。

(2)運算符和界符

: =  +  -  *  /  <  <=  <>  >  >=  =  ; (  )  #

(3)其他單詞是標識符(ID)和整型常數(SUM),通過以下正規式定義:

ID = letter (letter | digit)*

NUM = digit digit*

(4)空格有空白、制表符和換行符組成。空格一般用來分隔ID、SUM、運算符、界符和關鍵字,詞法分析階段通常被忽略。

4.1.2 各種單詞符號對應的種別碼:

表4.2.1 各種單詞符號對應的種別碼

單詞符號

種別碼

單詞符號

種別碼

bgin

1

17

If

2

:=

18

Then

3

<

20

wile

4

<>

21

do

5

<=

22

end

6

>

23

lettet(letter|digit)*

10

>=

24

dight dight*

11

=

25

+

13

26

14

(

27

*

15

)

28

/

16

#

0

 

 

4.2實現源碼參考

 

[html] 
#include <stdio.h> 
#include <string.h> 
 
char prog[80],token[8],ch; 
int syn,p,m,n,sum; 
char *rwtab[6]={"begin","if","then","while","do","end"}; 
  
void scaner(void); 
 
main() 

    p=0; 
    printf("\n please input a string(end with '#'):\n"); 
     
    do{ 
            scanf("%c",&ch); 
            prog[p++]=ch; 
    }while(ch!='#'); 
     
    p=0; 
    do{ 
            scaner(); 
            switch(syn) 
            { 
                case 11: 
                    printf("( %-10d%5d )\n",sum,syn); 
                break; 
                 
                case -1: 
                    printf("you have input a wrong string\n"); 
                    //getch(); 
                    return 0; 
                break; 
                 
                default:  
                printf("( %-10s%5d )\n",token,syn); 
                break; 
            } 
        }while(syn!=0); 
    //getch(); 
 } 
 
void scaner(void) 
{   
    sum=0; 
     
    for(m=0;m<8;m++) 
        token[m++]= NULL; 
     
        ch=prog[p++]; 
        m=0; 
         
    while((ch==' ')||(ch=='\n')) 
        ch=prog[p++]; 
     
    if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))) 
     {  
        while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) 
        { 
            token[m++]=ch; 
            ch=prog[p++]; 
        } 
         
        p--; 
        syn=10; 
 
        for(n=0;n<6;n++) 
        if(strcmp(token,rwtab[n])==0) 
        {  
            syn=n+1; 
            break; 
        } 
     } 
     else if((ch>='0')&&(ch<='9')) 
     {  
        while((ch>='0')&&(ch<='9')) 
        { 
            sum=sum*10+ch-'0'; 
            ch=prog[p++]; 
        } 
        p--; 
        syn=11; 
    } 
    else  
    { 
        switch(ch) 
        { 
        case '<': 
            token[m++]=ch; 
            ch=prog[p++]; 
            if(ch=='=') 
            {  
                syn=22; 
                token[m++]=ch; 
            } 
            else 
            {   
                syn=20; 
                p--; 
            } 
        break; 
 
        case '>': 
            token[m++]=ch; 
            ch=prog[p++]; 
            if(ch=='=') 
            { 
                syn=24; 
                token[m++]=ch; 
            } 
            else 
            {  
                syn=23; 
                p--; 
            } 
        break; 
 
        case '+': 
            token[m++]=ch; 
            ch=prog[p++]; 
            if(ch=='+') 
            { 
                syn=17; 
                token[m++]=ch; 
            } 
            else 
            { 
                syn=13; 
                p--; 
            } 
        break; 
 
        case '-': 
            token[m++]=ch; 
            ch=prog[p++]; 
            if(ch=='-') 
            { 
                syn=29; 
                token[m++]=ch; 
            } 
            else 
            {  
                syn=14; 
                p--; 
            } 
        break; 
 
        case '!': 
            ch=prog[p++]; 
            if(ch=='=') 
            {  
                syn=21; 
                token[m++]=ch; 
            } 
            else 
            {  
                syn=31; 
                p--; 
            } 
        break; 
 
        case '=': 
            token[m++]=ch; 
            ch=prog[p++]; 
            if(ch=='=') 
            { 
                syn=25; 
                token[m++]=ch; 
            } 
            else 
            { 
                syn=18; 
                p--; 
            } 
        break; 
 
        case '*': 
            syn=15; 
            token[m++]=ch; 
        break; 
 
        case '/': 
            syn=16; 
            token[m++]=ch; 
        break; 
 
        case '(':  
            syn=27; 
            token[m++]=ch; 
        break; 
 
        case ')': 
            syn=28; 
            token[m++]=ch; 
        break; 
 
        case '{':  
            syn=5; 
            token[m++]=ch; 
        break; 
 
        case '}':  
            syn=6; 
            token[m++]=ch; 
        break; 
 
        case ';': 
            syn=26; 
            token[m++]=ch; 
        break; 
 
        case '\"': 
            syn=30; 
            token[m++]=ch; 
        break; 
 
        case '#':  
            syn=0; 
            token[m++]=ch; 
        break; 
 
        case ':': 
            syn=17; 
            token[m++]=ch; 
        break; 
 
        default: 
            syn=-1; 
        break; 
        } 
    } 
        token[m++]='\0'; 

 

 

4.3小結:

詞法分析,就是將程序源代碼序列,循環讀取一個字串,然後根據詞法要求,確定其屬性,然後組成詞法單元。對於現實中的編程語言,其詞法比較復雜,一般用正則表達式表示。


作者:rill_zhen

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved