1. 程式人生 > >用C語言實現簡單的詞法分析器

用C語言實現簡單的詞法分析器

詞法分析器又稱掃描器。詞法分析是指將我們編寫的文字程式碼流解析為一個一個的記號,分析得到的記號以供後續語法分析使用。詞法分析器的工作是低級別的分析:將字元或者字元序列轉化成記號.。

要實現的詞法分析器單詞符號及種別碼對照表:

單詞符號 # begin if then while do End + - * / : : =
種別碼 0 1 2 3 4 5 6 13 14 15 16 17 18

單詞符號 < <> <= > >= = ; ( ) Letter(letter|digit) digit digit*
種別碼 20 21 22 23 24 25 26 27 28 10 11

#include<stdio.h>
#include<string.h>
char input[200];//存放輸入字串 
char token[5];//存放構成單詞符號的字串 
char ch;     //存放當前讀入字元 
int p;       //input[]下標 
int fg;     //switch標記 
int num;    //存放整形值 

//二維字元陣列,存放關鍵字 
char index[6][6]={"begin","if","then","while","do","end"};
main()
{
 p=0;
 printf("please intput string(End with '#'):\n");
do
{
 ch=getchar();
 input[p++]=ch;
}while(ch!='#');
p=0;
do
{
 scaner();
 switch(fg)
 {
  case 11:printf("( %d,%d )   ",fg,num);break;
  case -1:printf("input error\n");  break;
  default:printf("( %d,%s )   ",fg,token);
 }
}while(fg!=0);
getch(); //用於讓程式停留在顯示頁面
}
/*詞法掃描程式:*/
scaner()
{
	int m=0;//token[]下標 
	int n;
	
    //清空token[] 
    for(n=0;n<5;n++)
       token[n]=NULL;
  
    //獲取第一個不為0字元 
    ch=input[p++];
    while(ch==' ')ch=input[p++];
  
    //關鍵字(識別符號)處理流程 
    if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
       {
          while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0'))
             {
                 token[m++]=ch;
                 ch=input[p++];
             }
          token[m++]='\0';
          ch=input[--p];
          fg=10;
          for(n=0;n<6;n++)
             if(strcmp(token,index[n])==0)//strcmp()比較兩個字串,相等返回0 
                 {
                    fg=n+1;
                    break;
                 }
       }
       
     //數字處理流程 
     else if((ch<='9'&&ch>='0'))
     {
          num=0;
          while((ch<='9'&&ch>='0'))
          {
           num=num*10+ch-'0';
           ch=input[p++];
          }
           ch=input[--p];
           fg=11;
     }
     
     //運算子界符處理流程 
     else
         switch(ch)
          {
             case '<':
			     m=0;
				 token[m++]=ch;
                 ch=input[p++];
                 if(ch=='>')          //產生<> 
                   {
                      fg=21;
                      token[m++]=ch;
                    }
                 else if(ch=='=')     //產生<= 
                   {
                      fg=22;
                      token[m++]=ch;
                   }
                 else
                   {
                      fg=20;
                      ch=input[--p];
                   }
                 break;
		     case '>':
			     token[m++]=ch;
                 ch=input[p++];
                 if(ch=='=')        //產生>= 
                   {
                      fg=24;
                      token[m++]=ch;
                   }
                 else               //產生> 
                   {
                      fg=23;
                      ch=input[--p];
                   }
                 break; 
			 case ':':
			     token[m++]=ch;
                 ch=input[p++];
                 if(ch=='=')        //產生:= 
                   {
                      fg=18;
                      token[m++]=ch;
                   }
                 else              //產生: 
                   {
                      fg=17;
                      ch=input[--p];
                   }
                 break;
            case '+':fg=13;token[0]=ch;break;
            case '-':fg=14;token[0]=ch;break;
            case '*':fg=15;token[0]=ch;break;
            case '/':fg=16;token[0]=ch;break;
            case ':=':fg=18;token[0]=ch;break;
            case '<>':fg=21;token[0]=ch;break;
            case '<=':fg=22;token[0]=ch;break;
            case '>=':fg=24;token[0]=ch;break;
            case '=':fg=25;token[0]=ch;break;
            case ';':fg=26;token[0]=ch;break;
            case '(':fg=27;token[0]=ch;break;
            case ')':fg=28;token[0]=ch;break;
            case '#':fg=0;token[0]=ch;break;
            default:fg=-1;
        }
}