本文章实现内容:
以二元式形式输出单词(单词种类,值)
关键字: if、int、for、while、do、return、break、continue;单词种别码为1。
标识符;单词种别码为2
常数为无符号整形数;单词种别码为3。
运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。
分隔符包括: ,、;、{、}、(、);单词种别码为5;
输入数据举例:
编辑一个文本文件 text.txt,在文件中输入如下内容:
main()
{
int a,b;
a = 10;
b = a + 20;
}
输出结果
(2,“main”)
(5,“(”)
(5,“)”)
(5,“{”)
(1,“int”)
(2,“a”)
(5,“,”)
(2,“b”)
(5,“;”)
(2,“a”)
(4,“=”)
(3,“10”)
(5,“;”)
(2,“b”)
(4,“=”)
(2,“a”)
(4,“+”)
(3,“20”)
(5,“;”)
(5,“}”)
代码如下:
#include<stdio.h>
#include <string.h>
#define N 20
// 输出结果
void output(char *str,int a,int b,int type)
{
printf("(%d,“",type);
int i;
for(i=a;i<=b;i++)
printf("%c",str[i]);
printf("”)\n");
}
// 判断字符串一部分是否属于关键字
int iskeywords(char *str,int a,int b)
{
char keywords[8][10]={"if","int","for","while",
"do","return","break","continue"}; // 关键字
int i,n=8;
char s[20];
for(i=0;i<=b-a;i++) // 拷贝字符
s[i]=str[a+i];
s[i] = '\0';
for(i=0;i<n;i++) // 判断是否存在,存在返回1,否则返回2
{
if(strcmp(s,keywords[i])==0)
return 1;
}
return 2;
}
// 判断字符是否属于运算符或分隔符的一部分。
int belong_to(char str,int type)
{
int t = 0,i = 0,n;
char library[10];
if(type==4){
strcpy(library , "+-*/=><!"); // 运算符
n = 8;}
else{
strcpy(library , ",;{}()"); // 分隔符
n = 6;}
for(i=0;i<n;i++) // 判断是否存在,存在返回1或2,否则返回0
{
if(str == library[i])
{
if(type==4&&i>=4)// 后面能跟=号
t=2;
else
t=1;
return t;
}
}
return t;
}
// 分离+判断,打印输出类型
void scan(char *str,int n)
{
// 7种类型(最后输出1-5)
// -1
// 0: 初始
// 1: 关键字,在keywords中
// 2: 标识符
// 3: 常数(无符号整型)
// 4: 运算符和界符:+ - * / = > < >= <= !=
// 5: 分隔符: , ; { } ( )
int i,type=0;
for(i=n;i<strlen(str);i++)
{
switch(type)
{
case 0: // 初始态
if(str[i]==' '){ // 空格跳过
n+=1;
continue;}
else
if(str[i]=='\0'||str[i]=='\n') // 是结束
return;
else
if((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z'))
type = 1; //是字母,可能是关键字或标识符
else
if(str[i]>='0'&&str[i]<='9')
type = 3; //是数字,常数
else{
type = belong_to(str[i],4);
if(type >0) // 是运算符
{
if(type == 2&&str[i+1]=='=') //是能跟=号的运算符,后面是=号
i = i+1; // 结束位置后移
output(str,n,i,4); // 输出+递归+结束
scan(str,i+1);
return;
}
else
if(belong_to(str[i],5))//是分隔符
{
output(str,n,i,5); // 输出+递归+结束
scan(str,i+1);
return;
}
else{
printf("失败");
printf("%c",str[i]);
return;
}
}
break;
case 1:// 关键字或标识符
if(!((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')))
{//不是字母了
if(str[i]>='0'&&str[i]<='9') // 是数字
type = 2;
else // 非字母数字
{
type = iskeywords(str,n,i-1);
output(str,n,i-1,type); // 输出+递归+结束
scan(str,i);
return;
}
}
break;
case 2:// 标识符
if(!((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')))
{//不是字母了
if(!(str[i]>='0'&&str[i]<='9'))
{// 不是数字
output(str,n,i-1,type); // 输出+递归+结束
scan(str,i);
return;
}
}
break;
case 3:
if(!(str[i]>='0'&&str[i]<='9'))
{// 不是数字
output(str,n,i-1,type); // 输出+递归+结束
scan(str,i);
return;
}
break;
default :
printf("%d失败\n",type);
return;
}
}
return ;
}
int main()
{
FILE *p=fopen("text.txt","r"); //只读打开文件
if(p==NULL) // 没有文件提示
{
printf("缺少文件“text.txt”");
exit(0);
}
char str[20];
while(fgets(str, N, p) != NULL) // 一行一行读取
{
scan(str,0);
}
fclose(p); // 关闭文件
}