一個小語言的詞法分析程序原理及其實現(2)

(接上篇)根據這個表來構造程序,程序的核心是下面的這個函數,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

/********************************************************************

以下爲主分析函數

從輸入文件裏面讀,把分析結果寫到輸出文件中

參數:fpin :輸入文件指針  fpout: 輸出文件指針

********************************************************************/

void parse(FILE* fpin,FILE* fpout)

{

       char arr[MAXBUF];//讀出的最長的字符串不超過MAXBUF,MAXBUF定義爲255,夠長了我想

int i=0;//分析含字母的字符串用

       int j=0;//分析純數字的字符串用

    

 

       while(1)

       {

       fscanf(fpin,"%c",&ch);//從輸入文件中讀入一個字符

 

              if( ch==' '|| ch =='/t')//過濾掉空格和tab

                     ;

              else if( ch=='/n')//回車換行符,爲下面進行錯誤判斷

                     lineno++;

              else if( IsDigit(ch))//讀入的是數字

              {

                     while(IsDigit(ch))

                     {

                             

                            arr[j] = ch;

                            j++;

                            fscanf(fpin,"%c",&ch);

                           

                     }

                    

                  fseek(fpin,-1L,SEEK_CUR);//文件指針後退一個字節

 

                     char* temp1 =(char*)malloc(j+1);/

                     memcpy(temp1,arr,j);

                     temp1[j] ='/0';//把數組裏面的內容拷貝到連外一個數組裏面,因爲我定義的

                     //arr255個字節,實際上寫不到那麼多,所以只拷貝實際上有數據的

 

                     j=0;//恢復初始狀態,以備下次使用

                     fprintf(fpout,"%s/t/t%d/n",temp1,2);//常數

             

                     free(temp1);//釋放內存

                 

                    

              }

 

              else if(IsAlpha(ch))//是字母開頭的

              {

             

                     while(IsAlpha(ch) || IsDigit(ch))

                     {

                            arr[i] =ch;

                            i++;

                            fscanf(fpin,"%c",&ch);

                           

                     }

                     fseek(fpin,-1L,SEEK_CUR);

                    

                     char* temp = (char*)malloc(i+1) ;

                     memcpy(temp,arr,i);

                     temp[i] ='/0';

 

                     i=0;

                     /*基本思想同處理數字的*/

             

          if(FindOK(temp))//FindOK函數在關鍵字表中查找和temp字符串相同的,找到就返回類別編號

                {

                      

                      fprintf(fpout,"%s/t/t%d /n",temp,FindOK(temp));

                      

                }

                else

                {

                       fprintf(fpout,"%s/t/t%d/n",temp,1);//標示符號

                      

                }

                free(temp);

              }

      

              //以下爲2字節的運算符號

              else if( ch==':')//符號“:=”

              {

                     fscanf(fpin,"%c",&ch);

                     if(ch=='=')

                            fprintf(fpout,"%s/t/t%d/n",":=",20);

                    

              else       

                     fprintf(fpout,"error in compileing %d lines unknown character %c /n",lineno,ch);//出錯了

              }

 

              else if(ch=='>')//符號 > “ 和”>=”

              { 

                     fscanf(fpin,"%c",&ch);

                     if(ch=='=')

                     fprintf(fpout,"%s/t/t%d/n",">=",16);

                     else

                     fprintf(fpout,">/t/t15/n");

              }

              else if( ch=='<') //符號 < “ 和”<=”

 

              {

                     fscanf(fpin,"%c",&ch);

                     if(ch=='=')

                     {fprintf(fpout,"<=/t/t18/n");}

                     else if( ch=='>')

                     {fprintf(fpout,"<>/t/t19");}

                     else

                     {fprintf(fpout,"</t/t19/n");}

              }

      

 

              else {

            //以下爲一個字節的運算符號

              if(ch=='-') {fprintf(fpout,"%s/t/t%d/n",'-',10);continue;}//在文件中輸出爲“-   10

              if(ch==';') {fprintf(fpout,";/t/t21/n");continue;}

              if(ch=='+') {fprintf(fpout,"+/t/t9/n");continue;}

              if(ch=='*') {fprintf(fpout,"*/t/t11/n");continue;}

              if(ch=='/') {fprintf(fpout,"/ /t/t12/n");continue;}

              if(ch=='(') {fprintf(fpout,"(/t/t13/n");continue;}

              if(ch==')') {fprintf(fpout,")/t/t14/n");continue;}

              if(ch=='.') {fprintf(fpout,"./t/t22/n");continue;}

              if(ch==',') {fprintf(fpout,",/t/t23/n");continue;}

              if(ch=='#') break;//分析結束

              else fprintf(fpout,"error in compiling %d lines unknown character %c /n",lineno,ch);//出錯了,輸出出錯信息

              }

             

       }

      

 

}

以上代碼在VISUAL C++6.0 +WIN2000下編譯通過.

下面我們用該程序對下面的代碼進行詞法分析,該代碼保存爲test.txt,假設編譯後的應用程序爲lex.exe,

program test

 begin

       3j := 200 ;

if(j > 100) then      

  j := 300&&&&

else

  j := 107870

gyt768%^

 

end. #

在命令行下輸入源文件名,test.txt.以及輸出文件名:output.txt可以看到下面的結果.

 

program         6

test         1

begin              7

3            2

j             1

:=           20

200         2

;             21

if            3

(             13

j             1

>            15

100         2

)             14

then        4

j             1

:=           20

300         2

error in compiling 4 lines unknown character &

error in compiling 4 lines unknown character &

error in compiling 4 lines unknown character &

error in compiling 4 lines unknown character &

else         5

j             1

:=           20

107870           2

gyt768           1

error in compiling 7 lines unknown character %

error in compiling 7 lines unknown character ^

end         8

.             22

該函數是詞法分析程序的核心,它可以識別出源程序中的編寫錯誤,以及找出關鍵字,變量等.具體請看源代碼,註釋很詳細,但是肯定有不足的地方,請大家不吝賜教。有什麼問題,可以給我發郵件。。我的email[email protected],

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章