我们知道人类制造了计算机,计算机需要为我们的生活提供帮助,但是我们需要它帮助我们做什么、怎么做还是需要我们来告诉它,告诉它的过程就是通过一串又一串的字符串也就是代码来告诉它。但是代码对于计算机来说它还是不理解的,它只是辨识0与1而已,所以我们要进一步的将我们编写的程序代码进一步分解变化为机器码。在这过程中,使用的编译器就是完成这一工作的,词法分析程序就是其必不可少的部分。
词法分析是将输入的字符串以单词符号的结果进行输出,以下是便是关于词法规则和各种单词符号对应的种别码的相关图片


在这个词法分析程序中需具备以下的功能:
输入:源程序字符串
输出:二元组(种别,单词符号本身)
以下就是该程序的源代码:
#include"stdio.h"
#include"string.h"
#define MAX 200
char word[10][10]={"begin","if","then","while","do","end"};/*关键字对应的表*/
char word2[16][10]={"+","-","*","/",":",":=","","<","<=","<>",">",">=","=",";","(",")"};/*单词符号对应的表*/
char string[MAX];
char copy[20]="";/*用于缓存用户输入字符串片段*/
int temp=0;/*作为计数器使用*/
void Lexer();/*将用户输入字符串分解*/
void Number();/*识别字符串的数字*/
void Alphabet();/*识别字符串的字母及关键字*/
void Sign();/*识别界运算符*/
main()
{
char temp;
int i=0;
printf("请输入一段字符串($为结束标志):\n");
do{
temp=getchar();
string[i]=temp;
i++;
string[i]='\0';
}while(string[i-1]!='$');
Lexer(string);
}
void Lexer(char string[])/*将用户输入字符串分解*/
{
while(string[temp]!='\0')
{
if(string[temp]=='#'){printf("(%d,\'%c\')\n",0,'#');temp++;}
if(string[temp]==' '||string[temp]=='\n'||string[temp]=='\n'||string[temp]=='$')temp++;
Number();
Alphabet();
Sign();
}
}
void Number()/*识别字符串的数字*/
{
int i=temp;
if(string[i]>='0'&&string[i]<='9')/*判断是否为数字*/
{
while(string[i+1]>='0'&&string[i+1]<='9')/*如果是则对下一个字符进行判断;i作为计数器*/
i++;
if(temp!=i)
{
printf("(11,\'");
while(temp<=i)
{
printf("%c",string[temp]);
temp++;
}
printf("\')\n");
}
else
{
printf("(11,\'%c\')\n",string[temp]);
temp++;
}
}
}
void Alphabet()/*识别字符串的字母及关键字*/
{
int i,j;
if(string[temp]>='a'&&string[temp]<='z'||string[temp]=='_')/*判断是否为字母*/
{
i=temp;/*记录开始位置*/
while(string[temp+1]>='a'&&string[temp+1]<='z'||string[temp+1]=='_'||string[temp+1]>='0'&&string[temp+1]<='9')
temp++;/*如果符合规则对下一个字符进行判断;temp作为计数器*/
if(temp==i)
{
printf("(10,\'%c\')\n",string[i],string[i]);
temp++;
}
else
{
j=0;
while(i<=temp)
{
copy[j]=string[i];
i++;
j++;
}
for(i=0;i<10;i++)
if(strcmp(copy,word[i])==0)/*判断该字符串是否属于关键字*/
{
printf("(%d,\'%s\')\n",i+1,word[i]);
break;
}
temp++;
if(strcmp(copy,word[i])!=0)printf("(10,\'%s\')\n",copy);
}
}
}
void Sign()/*识别界运算符*/
{
int i,j;
for(i=0;i<20;i++)
copy[i]='\0';
if(string[temp]!='\0')
copy[0]=string[temp];
else return;
for(i=0;i<16;i++)
{
if(!strcmp(copy,word2[i]))/*先判断字符是否为表内的符号*/
{
copy[1]=string[temp+1];
for(j=0;j<16;j++)
if(!strcmp(copy,word2[j]))/*在第一个字符是的情况下判断两个字符是否为表内的符号*/
{
printf("(%d,\'%s\')\n",j+13,word2[j]);
temp+=2;
return;
}
printf("(%d,\'%s\')\n",i+13,word2[i]);
temp++;
return;
}
}
}
下图是程序运行后的截图:

这个词法分析程序的大致实现过程是:通过用户输入一段字符串,程序进行逐个字符的获取,避免遇到'\n','\t'等对输入的干扰,然后将字符存入字符数组添加'\0'成为字符串,接下来对字符串的元素进行读取,遇到字母等待进一步分析的不先输出,待分析后在单词符号表中查询。查询有则输出,没有则输出为标志符。对于一些组合而成的运算符也是如此,比如:>=,<=等。当然,数字的处理也是如此。
以上便是实现一个简单的词法分析程序的方法,当然,如果以上有不妥之处,也希望各位指教批评,多多交流。
















