输入以#结束,不能输入没有定义的字符。
1、 待分析的简单的词法
(1)关键字共9个:
main,int,char,if,,else,for,while,do,end
所有的关键字都是小写。
(2)运算符和界符
= ,+ ,* ,** ,; ,( ,) ,{ ,} ,< ,<= , > ,>= ,: ,:= ,/
(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:
ID = IsLetter (IsLetter IsDigit*)
NUM = IsDigit IsDigit*
illegal= IsDigit IsLetter*(还包括一些没有定义的字符)
2.各种单词符号对应的种别码
单词符号 | 种别编码 | 单词符号 | 种别编码 |
Illegal(不合法标识符) | 0 | * | 14 |
Main | 1 | ** | 15 |
int | 2 | ; | 16 |
char | 3 | ( | 17 |
if | 4 | ) | 18 |
else | 5 | { | 19 |
for | 6 | } | 20 |
while | 7 | < | 21 |
do | 8 | <= | 22 |
end | 9 | > | 23 |
ID(标识符) | 10 | >= | 24 |
NUM(常数) | 11 | : | 25 |
= | 12 | := | 26 |
+ | 13 | / | 27 |
源代码
#include <stdio.h>
#include <string.h>
#define N 100
char ch[100];
int Getchar();
void Reserve(int m,int n);
int IsLetter(int m);
int IsDigit(int n);
void main()
{
printf("请输入:\n");
gets(ch); //得到输入的字符
Getchar();
}
//将小标前移,记录字母的下标
int Getchar()
{
int len=0,i=0,j=0;
while(ch[len]!='#')
len++;
while(ch[i]!='#')
{
if(len==0)
printf("请输入字符:");
else
{
while(ch[i]==' ')//如果字符串的最前面是空格,则继续搜索,直到遇到字符串为止
i++;
}
j=i; //将遇到的第一个数的小标赋值给j
if(IsLetter(i))//如果第一个数为字母
{
i++; //数组下标向前移一位
while(IsLetter(i)||IsDigit(i))//判断向前移的那位只要不是空格就向前移一位,直到接受到的字符为空格为止
i++;
}
else if(IsDigit(i))// 如果第一个数为数字
{
i++;
while(IsDigit(i)||IsLetter(i))//如果接下来的数也为数字,记录其下标
i++;
}
else if(ch[i]=='=')
i++;
else if(ch[i]=='+')
i++;
else if(ch[i]=='*')
{
i++;
if(ch[i]=='*')
i++;
}
else if(ch[i]==';')
i++;
else if(ch[i]=='(')
i++;
else if(ch[i]==')')
i++;
else if(ch[i]=='{')
i++;
else if(ch[i]=='}')
i++;
else if(ch[i]=='<')
{
i++;
if(ch[i]=='=')
i++;
}
else if(ch[i]=='>')
{
i++;
if(ch[i]=='=')
i++;
}
else if(ch[i]==':')
{
i++;
if(ch[i]=='=')
i++;
}
else if(ch[i]=='/')
i++;
else
i++;
Reserve(j,i);
}
return 0;
}
//记录种类编码,打印出每个字符串极其所对应的种类编码
void Reserve(int m,int n)
{
int i,t,syn=0;
char str[N];
char *key[9]={"main","int","char","if","else","for","while","do","end"};
t=n-m;
strncpy(str,ch+m,t);//一行字符串以空格为分复制到str中
str[t]='\0';
if(IsLetter(m))// 若str的第一个数为字母
{
for(i=0;i<9;i++)
if((strcmp(str,key[i]))==0)//与关键字做比较
syn=i+1;
if(syn==0) //若没有相匹配的关键字,则为标识符
syn=10;
}
else if(IsDigit(m))
{
m++;
while(IsDigit(m))
m++;
if(m<n)
syn=0;
else
syn=11;
}
else if(ch[m]=='=')
syn=12;
else if(ch[m]=='+')
syn=13;
else if(ch[m]=='*')
{
if(ch[m]==ch[m+1])
syn=15;
else
syn=14;
}
else if(ch[m]==';')
syn=16;
else if(ch[m]=='(')
syn=17;
else if(ch[m]==')')
syn=18;
else if(ch[m]=='{')
syn=19;
else if(ch[m]=='}')
syn=20;
else if(ch[m]=='<')
{
if(ch[m+1]=='=')
syn=22;
else
syn=21;
}
else if(ch[m]=='>')
{
if(ch[m+1]=='=')
syn=24;
else
syn=23;
}
else if(ch[m]==':')
{
if(ch[m+1]=='=')
syn=26;
else
syn=25;
}
else if(ch[m]=='/')
syn=27;
else
syn=0;
printf("(%-10s %5d)\n",str,syn);
}
//判断是不是字母
int IsLetter(int m)
{
if(((ch[m]>='a')&& (ch[m]<='z'))||((ch[m]>='A')&& (ch[m]<='Z')))
return 1;
else
return 0;
}
//判断是不是数字
int IsDigit(int n)
{
if((ch[n]>='0') && (ch[n]<='9'))
return 1;
else
return 0;
}
运行结果