/*
实验要求:
编写词法分析器.
(1) 可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号.
(2) 可以识别并读取源程序中的注释.
(3) 可以统计源程序中的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,输出统计结果.
(4) 检查源程序中存在的非法字符错误,并可以报告错误所在的行列位置.
(5) 发现源程序中存在错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,
可以检查并报告源程序中存在的所有词法拼写错误.
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100
FILE *infile,*outfile; //stdio.h
char strToken[MAX]; //存放构成单词符号的字符串
char ch; //存放最新读进的源程序字符
int pos=0; //当前字符串的位置指针
int numberOflines=1; //统计行数
int numberOfwords=0; //统计源程序中单词个数,标点和空格不计为单词
int numberOfchars=-1; //统计源程序中字符个数 要去掉EOF
char GetChar()
{
ch = fgetc(infile);
if(ch == EOF)
printf("\n source.txt 的词法分析已完成,分析结果记录在 dest.txt\n\n");
numberOfchars++;
return ch;
}
void GetBC()//检查ch中字符是否空白 若是继续调用GetChar()直至非空
{
while(ch==' '||ch=='\t'||ch=='\b'||ch=='\n')
{
if(ch=='\n')
numberOflines++;
GetChar();
}
}
void Concat(char ch) //将ch中的字符连接到strToken后
{
strToken[pos++]=ch;
}
int IsLetter(char ch) //判断当前字符是否为字母
{
if((ch>='a' && ch<='z')||(ch>='A' && ch<='Z'))
return 1;
else return 0;
}
int IsDigit(char ch) //判断当前字符是否为数字
{
if(ch>='0' && ch<='9')
return 1;
else return 0;
}
int IsBound(char ch) //判断当前字符是否为分界符
{
if(ch=='.' || ch=='{' || ch=='}' || ch=='[' || ch==']' || ch=='(' || ch==')' || ch==',' || ch==';' ||
ch=='#' || ch=='\\' || ch=='\'' || ch=='\"' || ch=='\?' || ch==':')
return 1;
else return 0;
}
void Retract() //strToken回退,将ch置空
{
pos--;
ch=' ';
}
int KeyList(char strToken[]) //判断strToken中是否为关键字
{
if(strcmp(strToken,"auto")==0)
return 1;
else if(strcmp(strToken,"break")==0)
return 1;
else if(strcmp(strToken,"case")==0)
return 1;
else if(strcmp(strToken,"char")==0)
return 1;
else if(strcmp(strToken,"const")==0)
return 1;
else if(strcmp(strToken,"continue")==0)
return 1;
else if(strcmp(strToken,"default")==0)
return 1;
else if(strcmp(strToken,"double")==0)
return 1;
else if(strcmp(strToken,"do")==0)
return 1;
else if(strcmp(strToken,"else")==0)
return 1;
else if(strcmp(strToken,"enum")==0)
return 1;
else if(strcmp(strToken,"extern")==0)
return 1;
else if(strcmp(strToken,"float")==0)
return 1;
else if(strcmp(strToken,"for")==0)
return 1;
else if(strcmp(strToken,"goto")==0)
return 1;
else if(strcmp(strToken,"if")==0)
return 1;
else if(strcmp(strToken,"int")==0)
return 1;
else if(strcmp(strToken,"long")==0)
return 1;
else if(strcmp(strToken,"register")==0)
return 1;
else if(strcmp(strToken,"return")==0)
return 1;
else if(strcmp(strToken,"short")==0)
return 1;
else if(strcmp(strToken,"signed")==0)
return 1;
else if(strcmp(strToken,"sizeof")==0)
return 1;
else if(strcmp(strToken,"static")==0)
return 1;
else if(strcmp(strToken,"struct")==0)
return 1;
else if(strcmp(strToken,"switch")==0)
return 1;
else if(strcmp(strToken,"typedef")==0)
return 1;
else if(strcmp(strToken,"union")==0)
return 1;
else if(strcmp(strToken,"unsigned")==0)
return 1;
else if(strcmp(strToken,"void")==0)
return 1;
else if(strcmp(strToken,"volatile")==0)
return 1;
else if(strcmp(strToken,"while")==0)
return 1;
else return 0;
}
main()
{
if((infile=fopen("source.txt","r"))==NULL)
{
printf("Open source file error!\n");
exit(0);
}
if((outfile=fopen("dest.txt","w"))==NULL)
{
printf("Open dest file error!\n");
exit(0);
}
GetChar();
GetBC();
while(ch!=EOF)
{
//识别数字
if(IsDigit(ch))
{
pos=0;
while(IsDigit(ch))
{
Concat(ch);
GetChar();
}
//while循环在读到 数字开头+字母时报错
if(IsLetter(ch))
{
strToken[0]='\0';
printf("源程序第%d行有非法字符!程序将跳过非法字符进行后面的分析.\n",numberOflines);
while(IsLetter(ch))
GetChar();
}
strToken[pos++]='\0';
if(strToken[0]!='\0')
fprintf(outfile,"%s 数字\n",strToken);
numberOfwords++;
GetBC();
}
//识别关键字、标识符
else if(IsLetter(ch))
{
pos=0;
while(IsLetter(ch)||IsDigit(ch)||ch=='_')
{
Concat(ch);
GetChar();
}
strToken[pos++]='\0';
if(KeyList(strToken)==1)
fprintf(outfile,"%s 关键字\n",strToken);
else fprintf(outfile,"%s 标识符\n",strToken);
numberOfwords++;
GetBC();
}
//识别运算符(算术运算符 关系运算符 逻辑运算符 赋值运算符 不包括位运算符)
else if(ch=='+') //+,++,+=
{
pos=0;
Concat(ch);
GetChar();
if(ch=='+'||ch=='=')
{
Concat(ch);
strToken[pos++]='\0';
fprintf(outfile,"%s 运算符\n",strToken);
GetChar();
GetBC();
}
else
{
strToken[pos++]='\0';
fprintf(outfile,"%s 运算符\n",strToken);
GetBC();//此情况下ch不应该用GetChar()
}
}
else if(ch=='-') //-,--,-=
{
pos=0;
Concat(ch);
GetChar();
if(ch=='-'||ch=='=')
{
Concat(ch);
strToken[pos++]='\0';
fprintf(outfile,"%s 运算符\n",strToken);
GetChar();
GetBC();
}
else
{
strToken[pos++]='\0';
fprintf(outfile,"%s 运算符\n",strToken);
GetBC();
}
}
else if(ch=='*' || ch=='%' || ch=='!' || ch=='>' || ch=='<' || ch=='=')
//*,*=,%,%=!,!=,>,>=,<,<=,=,==
{
pos=0;
Concat(ch);
GetChar();
if(ch=='=')
{
Concat(ch);
strToken[pos++]='\0';
fprintf(outfile,"%s 运算符\n",strToken);
GetChar();
GetBC();
}
else
{
strToken[pos++]='\0';
fprintf(outfile,"%s 运算符\n",strToken);
GetBC();
没有合适的资源?快使用搜索试试~ 我知道了~
CIFAFENXI.rar_c 词法分析 错误_拼写检查器_词法分析 恢复
共1个文件
c:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 160 浏览量
2022-09-23
10:26:45
上传
评论 2
收藏 2KB RAR 举报
温馨提示
C语言 词法分析器。 (1) 可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号. (2) 可以识别并读取源程序中的注释. (3) 可以统计源程序中的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,输出统计结果. (4) 检查源程序中存在的非法字符错误,并可以报告错误所在的行列位置. (5) 发现源程序中存在错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理, 可以检查并报告源程序中存在的所有词法拼写错误.
资源详情
资源评论
资源推荐
收起资源包目录
CIFAFENXI.rar (1个子文件)
CIFAFENXI.c 11KB
共 1 条
- 1
我虽横行却不霸道
- 粉丝: 95
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0