编译原理实验之源程序的预处理及词法分析程序设计
2014-09-08 23:41
639 查看
题目要求:
1、实现预处理功能
源程序中可能包含有对程序执行无意义的符号,要求将其剔除。
首先编制一个源程序的输入过程,从键盘、文件或文本框输入若干行语句,依次存入输入缓冲区(字符型数据);然后编制一个预处理子程序,去掉输入串中的回车符、换行符和跳格符等编辑性文字;把多个空白符合并为一个;去掉注释。
2、实现词法分析功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。其中,
syn为单词种别码。
Token为存放的单词自身字符串。
Sum为整型常量。
具体实现时,可以将单词的二元组用结构进行处理。
3、待分析的C语言子集的词法
1)关键字
main if then while do static int double struct break else long switch case typedef char return const float short continue for void default sizeof do
所有的关键字都是小写。
2)运算符和界符
+ - * / : := < <> <= > >= = ; ( ) #
3)其他标记ID和NUM
通过以下正规式定义其他标记:
ID→letter(letter|digit)*
NUM→digit digit*
letter→a|…|z|A|…|Z
digit→0|…|9…
4)空格由空白、制表符和换行符组成
空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。
4、各种单词符号对应的种别码
表1 各种单词符号的种别码
单词符号 种别码 单词符号 种别码
main 1 ; 41
if 2 ( 42
then 3 ) 43
while 4 int 7
do 5 double 8
static 6 struct 9
ID 25 break 10
NUM 26 else 11
+ 27 long 12
- 28 switch 13
* 29 case 14
/ 30 typedef 15
: 31 char 16
:= 32 return 17
< 33 const 18
<> 34 float 19
<= 35 short 20
> 36 continue 21
>= 37 for 22
= 38 void 23
default 39 sizeof 24
do 40 # 0
题目要求如上,鄙人自己写的如下(这是早几个月前写的,没有再检查对错,由于当初老师给的实验要求就有问题所以里面的会有一些小问题不影响,且鄙人写代码习惯写注释比较好理解):
第一步代码:
#include<stdio.h>
#include<String.h>
int main(){
FILE *p;
int falg = 0,len,i=0,j=0;//
char str[1000],str1[1000],c;
if((p=fopen("e:\\test.txt","rt"))==NULL){
printf("无法打开");
return 0;
}
else{
//fgets(str,1000,p);
while((c=getc(p))!=EOF){
str[i++] = c;
}
fclose(p);
str[i] = '\0';
for(i=0;i<strlen(str);i++){
if(str[i]=='/'&&str[i+1]=='/'){
while(str[i++]!='\n'){}
}//单行注释
else if(str[i]=='/'&&str[i+1]=='*'){
while(!(str[i]=='*'&&str[i+1]=='/')){i++;}
i+=2;
}//多行注释
else if(str[i]==' '&&str[i+1]==' '){
while(str[i]==' '){i++;}
i--;
if(str1[j-1]!=' ')
str1[j++]=' ';
}//多个空格,去除空格
else if(str[i]=='\n') {
if(str1[j-1]!=' ')
str1[j++]=' ';
}//换行处理,
else if(str[i]==9){
while(str[i]==9){
i++;
}
if(str1[j-1]!=' ')
str1[j++]=' ';
i--;
}//tab键处理
else str1[j++] = str[i];//其他字符处理
}
str1[j] = '\0';
// printf("%s\n",str);
// printf("%s\n",str1);
/*
for(int k=0;k<strlen(str1);k++){
if(str1[k]!=' ')
printf("%c",str1[k]);
else printf("_");
}
*/
if((p = fopen("e:\\test1.txt","w"))==NULL){
printf("can not find it!");
return 0;
}
else{
if(fputs(str1,p)!=0){
printf("存储失败!");
}
else printf("存储成功!");
}
fclose(p);
}
return 0;
}
第二部分代码:
代码已粘上,如有什么漏洞都可再与鄙人联系。欢迎评论。
1、实现预处理功能
源程序中可能包含有对程序执行无意义的符号,要求将其剔除。
首先编制一个源程序的输入过程,从键盘、文件或文本框输入若干行语句,依次存入输入缓冲区(字符型数据);然后编制一个预处理子程序,去掉输入串中的回车符、换行符和跳格符等编辑性文字;把多个空白符合并为一个;去掉注释。
2、实现词法分析功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。其中,
syn为单词种别码。
Token为存放的单词自身字符串。
Sum为整型常量。
具体实现时,可以将单词的二元组用结构进行处理。
3、待分析的C语言子集的词法
1)关键字
main if then while do static int double struct break else long switch case typedef char return const float short continue for void default sizeof do
所有的关键字都是小写。
2)运算符和界符
+ - * / : := < <> <= > >= = ; ( ) #
3)其他标记ID和NUM
通过以下正规式定义其他标记:
ID→letter(letter|digit)*
NUM→digit digit*
letter→a|…|z|A|…|Z
digit→0|…|9…
4)空格由空白、制表符和换行符组成
空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。
4、各种单词符号对应的种别码
表1 各种单词符号的种别码
单词符号 种别码 单词符号 种别码
main 1 ; 41
if 2 ( 42
then 3 ) 43
while 4 int 7
do 5 double 8
static 6 struct 9
ID 25 break 10
NUM 26 else 11
+ 27 long 12
- 28 switch 13
* 29 case 14
/ 30 typedef 15
: 31 char 16
:= 32 return 17
< 33 const 18
<> 34 float 19
<= 35 short 20
> 36 continue 21
>= 37 for 22
= 38 void 23
default 39 sizeof 24
do 40 # 0
题目要求如上,鄙人自己写的如下(这是早几个月前写的,没有再检查对错,由于当初老师给的实验要求就有问题所以里面的会有一些小问题不影响,且鄙人写代码习惯写注释比较好理解):
第一步代码:
#include<stdio.h>
#include<String.h>
int main(){
FILE *p;
int falg = 0,len,i=0,j=0;//
char str[1000],str1[1000],c;
if((p=fopen("e:\\test.txt","rt"))==NULL){
printf("无法打开");
return 0;
}
else{
//fgets(str,1000,p);
while((c=getc(p))!=EOF){
str[i++] = c;
}
fclose(p);
str[i] = '\0';
for(i=0;i<strlen(str);i++){
if(str[i]=='/'&&str[i+1]=='/'){
while(str[i++]!='\n'){}
}//单行注释
else if(str[i]=='/'&&str[i+1]=='*'){
while(!(str[i]=='*'&&str[i+1]=='/')){i++;}
i+=2;
}//多行注释
else if(str[i]==' '&&str[i+1]==' '){
while(str[i]==' '){i++;}
i--;
if(str1[j-1]!=' ')
str1[j++]=' ';
}//多个空格,去除空格
else if(str[i]=='\n') {
if(str1[j-1]!=' ')
str1[j++]=' ';
}//换行处理,
else if(str[i]==9){
while(str[i]==9){
i++;
}
if(str1[j-1]!=' ')
str1[j++]=' ';
i--;
}//tab键处理
else str1[j++] = str[i];//其他字符处理
}
str1[j] = '\0';
// printf("%s\n",str);
// printf("%s\n",str1);
/*
for(int k=0;k<strlen(str1);k++){
if(str1[k]!=' ')
printf("%c",str1[k]);
else printf("_");
}
*/
if((p = fopen("e:\\test1.txt","w"))==NULL){
printf("can not find it!");
return 0;
}
else{
if(fputs(str1,p)!=0){
printf("存储失败!");
}
else printf("存储成功!");
}
fclose(p);
}
return 0;
}
第二部分代码:
#include<stdio.h> #include<String.h> int main(){ FILE *p; int falg = 0,len,i=0,j=0;// char *rwtab[27]={"","main","if","then","while","do", "static","int","double","struct","break","else","long", "switch","case","typedef","char","return","const","float", "short","continue","for","void","sizeof","default","do"};//26个 char str[1000],str1[1000],c; int syn,num; char token[200]; if((p=fopen("e:\\test1.txt","rt"))==NULL){ printf("无法打开"); return 0; } //fgets(str,1000,p); while((c=getc(p))!=EOF){ str[i++] = c; } fclose(p); if((p=fopen("e:\\test2.txt","w"))==NULL){ printf("无法打开"); return 0; } str[i] = '\0'; //printf("%s\n",str); for(i=0;str[i]!='\0';){ j = 0; num = -1; if((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')||str[i]=='_'){ while((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')||(str[i]>='0'&&str[i]<='9')||str[i]=='_'){ token[j++] = str[i++]; } token[j] = '\0'; for(int k=1;k<27;k++){ if(strcmp(rwtab[k],token)==0) break; } if(k<25) syn = k; else if(k==25) syn = 39; else if(k==26) syn = 40; else syn = 25; }//关键字和标示符处理 else if((str[i]>='0'&&str[i]<='9')&&((str[i+1]>='a'&&str[i+1]<='z')|| (str[i+1]>='A'&&str[i+1]<='Z')||str[i+1]=='_'||(str[i+1]>='0'&&str[i+1]<='9'))){ syn = -3; while((str[i]>='a'&&str[i]<='z')|| (str[i]>='A'&&str[i]<='Z')||str[i]=='_'||(str[i]>='0'&&str[i]<='9')){ token[j++] = str[i++]; } i--; } else if(str[i]>='0'&&str[i]<='9'){ num = 0; while(str[i]>='0'&&str[i]<='9'){ num = num*10+str[i++]-'0'; } syn = 26; }//数字在此处处理 else {//printf("%c********************************\n",str[i]); if(str[i]==':'&&str[i+1]=='='){ syn = 32; token[j++] = str[i]; token[j++] = str[i++]; } else if(str[i]=='<'&&str[i+1]=='>'){ syn = 34; token[j++] = str[i]; token[j++] = str[i++]; } else if(str[i]=='<'&&str[i+1]=='='){ syn = 35; token[j++] = str[i]; token[j++] = str[i++]; } else if(str[i]=='>'&&str[i+1]=='='){ syn = 36; token[j++] = str[i]; token[j++] = str[i++]; } else if(str[i]==' '){ i++; syn = -2; }//空格处理 /* else if(str[i]!=' '){ syn = -1; while(str[i++]!=' '){ token[j++] = str[i]; } }//不明字符的处理 */ else{ switch(str[i]){ case '+': syn = 27;break; case '-': syn = 28;break; case '*': syn = 29;break; case '/': syn = 30;break; case ':': syn = 31;break; case '<': syn = 33;break; case '>': syn = 36;break; case ';': syn = 41;break; case ')': syn = 43;break; case '(': syn = 42;break; case '#': syn = 0;break; case '=':syn = 38;break; default: syn = -1;break; } //printf("%c********************************\n",str[i]); token[j++] = str[i++]; } } token[j] = '\0'; if(num!=-1){ printf("%d %d\n",num,syn); fprintf(p,"%d %d\n",num,syn); char A[100]; int i=0; while(num){ A[i++] = num%2; num = num/2; } for(i--;i>=0;i--){ printf("%c ",A[i]+'0'); fprintf(p,"%c ",A[i]+'0'); } printf(" %d\n",syn); fprintf(p,"%d\n",syn); } else if(syn!=-1&&syn !=-2 &&syn!=-3){ printf("%s %d\n",token,syn); fprintf(p,"%s %d\n",token,syn); } else if(syn==-1){ printf("%s error\n",token); fprintf(p,"%s error\n",token); } else if(syn == -3){ printf("%s error ID\n",token); fprintf(p,"%s error ID\n",token); } } fclose(p); return 0; }
代码已粘上,如有什么漏洞都可再与鄙人联系。欢迎评论。
相关文章推荐
- 实验一 源程序的预处理及词法分析程序设计
- 编译原理 实验3 语法分析
- 编译原理程序设计实践(三) 错误处理和词法分析代码
- 编译原理实验二:语义分析
- 编译原理实验一:为PL/0语言编写一个词法分析程序
- 编译原理实验一分析
- 编译原理课程实验--词法分析
- 编译原理 实验总结及实现分析 递归下降与算符优先原理
- 编译原理实验二分析
- 编译原理实验4——LL(1)文法分析
- 编译原理丨第七周 ——1000. 词法分析程序设计 **
- 编译原理 实验3 递归下降语法分析程序设计
- 哈工大软件学院编译原理实验1——词法分析
- CSUFT 编译原理实验二LL(1)文法分析
- 设计有穷自动机DFA实现C++简单程序的词法分析、扫描(编译原理实验) 推荐
- 编译原理 实验1 PL/0语言词法分析
- 编译原理语义分析(文本输入)源程序
- 编译原理-LL(1)预测分析实验 c源代码
- 编译原理实验2-递归下降分析–表达式求值
- 编译原理实验---词法分析