输入以#结束,不能输入没有定义的字符。
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;
}
运行结果