?? 詞法分析的c實現(做編譯器的時候很有用).txt
字號:
作者:skyhorsebj
email: XUEY@CIDC.COM.CN
日期:2001-7-3 12:41:52
這里以開始定義的PASCAL語言子集的源程序作為詞法分析程序的輸入數據。
在詞法分析中,自文件頭開始掃描源程序字符,一旦發現符合"單詞"定義的源程
序字符串時,將它翻譯成固定長度的單詞內部表示,并查填適當的信息表。經過
詞法分析后,源程序字符串(源程序的外部表示)被翻譯成具有等長信息的單詞
串(源程序的內部表示),并產生兩個表格:常數表和標識符表,它們分別包含
了源程序中的所有常數和所有標識符。
下面就詞法分析程序中的主要變量進行說明:
FILE fp :文件指針,用于指向要分析的PASCAL源程序;
char *key[8]:指針數組,用于指向關鍵字表;
char *border[6]:指針數組,用于指向符號表;
char *arithmetic[4]:指針數組,指向算術運算符表;
char *relation[6]:指針數組,指向關系運算符表;
char *consts[20]:指針數組,指向常數表;
char *label[20]:指針數組,指向標識符表;
int constnum,labelnum:整型變量,分別用于存放當前常數個數和標
識符個數。
程序中的主要子函數:
alphaprocess:關鍵字和標識符處理子函數;
digitprocess:數字處理函數;
otherprocess:其他字符處理函數;
search:查找子函數;
下面簡要分析一下詞法分析程序的運行流程:
主函數main():
打開要分析的PASCAL源程序,若不能正確打開,則報錯。
先從源程序中讀入一個字符ch,然后進行如下處理:
1、ch是字符:轉入關鍵字和標識符處理子函數;
2、ch是數字:轉入數字處理函數;
3、ch是其他字符:轉入其他字符處理子函數;
結束。
關鍵字和標識符處理子函數alphaprocess(char buffer);
1、將buffer送入臨時數組alphatp[0],再讀入一個字符至buffer;
2、判斷buffer是否為字符或數字,若是,則alphatp[1]=buffer;
3、重復1,2,直到2判斷為假;在alphatp末尾添加'\0';
4、調用search()子函數,在關鍵字表中匹配alphatp,若匹配成功,則返回序號;
5、調用search,在標識符表中匹配alphatp,若匹配成功,則返回序號;
6、在標識符表中添加alphatp,并返回序號;
其余子函數的處理方式于alphaprocess類似,此處不再贅述。
[程序調試]
現有PASCAL程序清單如下:
BEGIN
IF I=1 THEN
I:=I+1 #
ELSE *&^
IF I=2 THEN
I:=I+11;
END.
運行詞法分析程序后,顯示如下結果:
BEGIN (1,1)
IF (1,4)
I (6,0)
= (4,2)
1 (5,0)
THEN (1,5)
I (6,0)
:= (2,2)
I (6,0)
+ (3,0)
1 (5,0)
# error,not a word
ELSE (1,2)
* (3,2)
& error,not a word
^ error,not a word
IF (1,4)
I (6,0)
= (4,2)
2 (5,1)
THEN (1,5)
I (6,0)
:= (2,2)
I (6,0)
+ (3,0)
11 (5,2)
; (2,1)
END (1,3)
. (2,3)
over
結果完全正確。
源程序:
#include
#include
#include
#include
#include
#define NULL 0
FILE *fp;
char cbuffer;
char *key[8]={"DO","BEGIN","ELSE","END","IF","THEN","VAR","WHILE"};
char *border[6]={",",";",":=",".","(",")"};
char *arithmetic[4]={"+","-","*","/"};
char *relation[6]={"<","<=","=",">",">=","<>"};
char *consts[20];
char *label[20];
int constnum=0,labelnum=0;
int search(char searchchar[],int wordtype)
{
int i=0;
switch (wordtype) {
case 1:for (i=0;i<=7;i++)
{
if (strcmp(key[i],searchchar)==0)
return(i+1);
};
case 2:{for (i=0;i<=5;i++)
{
if (strcmp(border[i],searchchar)==0)
return(i+1);
};
return(0);
}
case 3:{for (i=0;i<=3;i++)
{
if (strcmp(arithmetic[i],searchchar)==0)
{
return(i+1);
};
};
return(0);
};
case 4:{for (i=0;i<=5;i++)
{
if (strcmp(relation[i],searchchar)==0)
{
return(i+1);
};
};
return(0);
};
case 5:{for (i=0;i<=constnum;i++)
{
if (strcmp(consts[i],searchchar)==0)
{
return(i+1);
};
}
consts[i-1]=(char *)malloc(sizeof(searchchar));
strcpy(consts[i-1],searchchar);
constnum++;
return(i);
};
case 6:{for (i=0;i<=labelnum;i++)
{
if (strcmp(label[i],searchchar)==0)
{
return(i+1);
};
}
label[i-1]=(char *)malloc(sizeof(searchchar));
strcpy(label[i-1],searchchar);
labelnum++;
return(i);
};
}
}
char alphaprocess(char buffer)
{
int atype;
int i=-1;
char alphatp[20];
while ((isalpha(buffer))||(isdigit(buffer)))
{
alphatp[++i]=buffer;
buffer=fgetc(fp);
};
alphatp[i+1]='\0';
if (atype=search(alphatp,1))
printf("%s (1,%d)\n",alphatp,atype-1);
else
{
atype=search(alphatp,6);
printf("%s (6,%d)\n",alphatp,atype-1);
};
return(buffer);
}
char digitprocess(char buffer)
{
int i=-1;
char digittp[20];
int dtype;
while ((isdigit(buffer)))
{
digittp[++i]=buffer;
buffer=fgetc(fp);
}
digittp[i+1]='\0';
dtype=search(digittp,5);
printf("%s (5,%d)\n",digittp,dtype-1);
return(buffer);
}
char otherprocess(char buffer)
{
int i=-1;
char othertp[20];
int otype,otypetp;
othertp[0]=buffer;
othertp[1]='\0';
if (otype=search(othertp,3))
{
printf("%s (3,%d)\n",othertp,otype-1);
buffer=fgetc(fp);
goto out;
};
if (otype=search(othertp,4))
{
buffer=fgetc(fp);
othertp[1]=buffer;
othertp[2]='\0';
if (otypetp=search(othertp,4))
{
printf("%s (4,%d)\n",othertp,otypetp-1);
goto out;
}
else
othertp[1]='\0';
printf("%s (4,%d)\n",othertp,otype-1);
goto out;
};
if (buffer==':')
{
buffer=fgetc(fp);
if (buffer=='=')
printf(":= (2,2)\n");
buffer=fgetc(fp);
goto out;
}
else
{
if (otype=search(othertp,2))
{
printf("%s (2,%d)\n",othertp,otype-1);
buffer=fgetc(fp);
goto out;
}
};
if ((buffer!='\n')&&(buffer!=' '))
printf("%c error,not a word\n",buffer);
buffer=fgetc(fp);
out: return(buffer);
}
void main()
{
int i;
for (i=0;i<=20;i++)
{
label[i]=NULL;
consts[i]=NULL;
};
if ((fp=fopen("\\DEMO.PAS","r"))==NULL)
printf("error");
else
{
cbuffer = fgetc(fp);
while (cbuffer!=EOF)
{
if (isalpha(cbuffer))
cbuffer=alphaprocess(cbuffer);
else if (isdigit(cbuffer))
cbuffer=digitprocess(cbuffer);
else cbuffer=otherprocess(cbuffer);
};
printf("over\n");
};
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -