当前位置:网站首页>编译原理:源程序的预处理及词法分析程序的设计与实现(含代码)
编译原理:源程序的预处理及词法分析程序的设计与实现(含代码)
2022-07-06 09:17:00 【俊夫小瞳】
源程序的预处理及词法分析程序的设计与实现
写在最前面:代码按着自己的想法写的,与这个博客讲的方法有不一样的地方。
另:我的代码是从文档中读取需要处理的代码,处理完之后打印在另两个个文档,直接复制可能无法运行,需要自己创建三个文档:文档一(源代码);文档二(预处理之后的源代码);文档三(二元组)。记得检查文件位置和名字是否正确。
一、实验目的
设计并实现一个包含预处理功能的词法分析程序,加深对编译中词法分析过程的理解。
二、 实验要求
1、实现预处理功能
源程序中可能包含有对程序执行无意义的符号,要求将其剔除。
首先编制一个源程序的输入过程,从键盘、文件或文本框输入若干行语句,依次存入输入缓冲区(字符型数据);
然后编制一个预处理子程序,去掉输入串中的回车符、换行符和跳格符等编辑性文字;
把多个空白符合并为一个;
去掉注释。
2、实现词法分析功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中,syn为单词种别码。Token为存放的单词自身字符串。Sum为整型常量。
具体实现时,可以将单词的二元组用结构进行处理。
3、待分析的C语言子集的词法(可以自行扩充,也可以按照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 |
5、 词法分析程序的主要算法思想
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到的单词符号的第一个字符的种类,拼出相应的单词符号。
1.主程序示意图
其中初值包括如下两方面:
(1) 关键字表初值
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关
键字表为一个字符串数组,其描述如下:
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”,”default”,”sizeof”,”do”};
(2) 程序中需要用到的主要变量:syn,token和sum。
2.扫描子程序的算法思想
首先设置三个变量:
token用来存放构成单词符号的字符串;
sum用来存放整型单词;
syn用来存放单词符号的种别编码。
扫描子程序主要部分流程如图2所示。
三、实验代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char key[26][20] = {
"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"};
//da yin
void p(char* str)
{
printf("%s\n",str);
}
//shan chu kong ge
void deblank(char *str)
{
char s[10000];
char s1[10000]={
NULL};
int i=0,j=0,next=0;
strcpy(s,str);
while(s[j]!=EOF)
{
s1[i]=s[j];
i++;
j++;
if(s[j-1]==' ')
{
next=j;
while(s[next]==' ')next++;
j=next;
}
// if(s[j]!=' ')
// {
// str[i]=s[j];
// i++;
// j++;
// }
// else
// {
// str[i]=s[j];
// i++;
// j++;
// next=j;
// while(s[next]==' ')next++;
// j=next;
// }
}
// while(str[i++]!='\0')str[i-1]='\0';
// p(s1);
strcpy(str,s1);
}
//shan chu zhu shi
void zhushi(char *str)
{
int i,j;
char s[10000];
strcpy(s,str);
for(i=0,j=0;s[i]!=EOF;i++,j++)
{
if(s[i]=='/'&&s[i+1]=='/')
{
str[j]=' ';
while(s[i]!='\n')i++;
}
else
{
str[j]=s[i];
}
}
strcpy(s,str);
for(i=0,j=0;s[i]!=EOF;i++,j++)
{
if(s[i]=='/'&&s[i+1]=='*')
{
str[j]=' ';
while(s[i]!='*'||s[i+1]!='/')
{
i++;
if(s[i]==EOF)
{
printf("注释有误。\n");
system("pause");
exit(0);
}
}
i=i+1;
}
else
{
str[j]=s[i];
}
}
deblank(str);
// p(str);
}
//shan chu hui che haun hang
void enter(char *str)
{
int i,j=0;
char s[10000];
strcpy(s,str);
for(i=0;s[i]!=EOF;i++,j++)
{
if(s[i]=='\n'||s[i]=='\r'||s[i]=='\t')
{
s[i]=' ';
str[j]=s[i];
}
else
{
str[j]=s[i];
}
}
// p(str);
}
int zm(char a)
{
if(a>='a'&&a<='z'||a>='A'&&a<='Z')
{
return 1;
}
else
{
return 0;
}
}
int sz(char a)
{
if(a>='0'&&a<='9')
{
return 1;
}
else
{
return 0;
}
}
void xr(char *a,int b)
{
FILE *fp;
fp=fopen("D:\\app\\vscode\\codes\\compilation\\exp1-3.txt","a");
if(fp==NULL)
{
printf("fail to open the file!\n");
system("pause");
exit(0);
}
if(b>=0)
{
fprintf(fp, "<%s,%d>\n", a, b);
}
else
{
fprintf(fp, "无法识别\"%c\"\n",a[0]);
}
fclose(fp);
}
void id(char *a)
{
int i,b;
for(i = 0; i<26;i++)
{
if(strcmp(a,key[i]) == 0)
{
if(i<24)
{
b=i+1;
}
else
{
if(i==24) b=39;
if(i==25) b=40;
}
xr(key[i],b);
return;
}
}
xr(a,25);
}
void cffx()
{
FILE *fp;
char ch;
char str[10000];
char word[50];
char numb[50];
int i,j,k;
fp=fopen("D:\\app\\vscode\\codes\\compilation\\exp1-2.txt","r");
if(fp==NULL)
{
printf("fail to open the file!\n");
exit(0);
}
i=0;
while((ch=fgetc(fp))!=EOF)
{
str[i]=ch;
i++;
}
for(i=0,j=0,k=0;str[i]!=NULL;i++)
{
int a,b;
a=zm(str[i]);
if(a==1)
{
word[j]=str[i];
j++;
for(;;)
{
i++;
a=zm(str[i]);
b=sz(str[i]);
if(a==1||b==1)
{
word[j]=str[i];
j++;
}
else
{
id(word);
memset(word,0,sizeof(word));
j=0;
break;
}
}
i--;
continue;
}
a=sz(str[i]);
if(a==1)
{
numb[k]=str[i];
k++;
for(;;)
{
i++;
a=sz(str[i]);
if(a==1||str[i]=='e'||str[i]=='E'||str[i]=='.')
{
if(str[i]=='.'&&sz(str[i+1])==0)
{
printf("小数点错误。\n");
system("pause");
exit(0);
}
numb[k]=str[i];
k++;
}
else
{
xr(numb,26);
memset(numb,0,sizeof(numb));
k=0;
break;
}
}
i--;
continue;
}
if(str[i]==' ')
{
continue;
}
switch(str[i])
{
case '+': xr((char*)"+",27);break;
case '-': xr((char*)"-",28);break;
case '*': xr((char*)"*",29);break;
case '/': xr((char*)"/",29);break;
case '=': xr((char*)"=",38);break;
case ';': xr((char*)";",41);break;
case '(': xr((char*)"(",42);break;
case ')': xr((char*)")",43);break;
case '#': xr((char*)"#",0);break;
case '.': xr((char*)".",-1);break;
case '{': xr((char*)"{",-1);break;
case '}': xr((char*)"}",-1);break;
case '%': xr((char*)"%",-1);break;
case '\"': xr((char*)"\"",-1);break;
case '\\': xr((char*)"\\",-1);break;
case ',': xr((char*)",",-1);break;
case '|':
if(str[i+1] == '|')
{
i++;
xr((char*)"||",-1);
}
else
{
xr((char*)"|",-1);
}
break;
case '&':
if(str[i+1] == '&')
{
i++;
xr((char*)"&&",-1);
}
else
{
xr((char*)"&",-1);
}
break;
case ':':
if(str[i+1] == '=')
{
i++;
xr((char*)":=",32);
}
else
{
xr((char*)":",31);
}
break;
case '<':
if(str[i+1] == '>')
{
i++;
xr((char*)"<>",34);
}
else if(str[i+1] == '=')
{
i++;
xr((char*)"<=",35);
}
else
{
xr((char*)"<",33);
}
break;
case '>':
if(str[i+1] == '=')
{
i++;
xr((char*)">=",37);
}
else
{
xr((char*)">",36);
}
break;
// default : xr(&str[i],-1);break;
}
}
}
int main()
{
FILE *fp;
char ch;
char str[10000];
int i=0;
fp=fopen("D:\\app\\vscode\\codes\\compilation\\exp1-1.txt","r");
if(fp==NULL)
{
printf("fail to open the file!\n");
exit(0);
}
else
{
// printf("The file is open!\n");
while((ch=fgetc(fp))!=EOF)
{
str[i]=ch;
i++;
// putchar(ch);
}
// printf("%s\n",str);
// 读取文件内容:
// 1.
// while((ch=fgetc(fp))!=EOF)putchar(ch);
// 2.
// ch=fgetc(fp);
// while(ch!=EOF)
// {
// putchar(ch);
// ch=fgetc(fp);
// }
// 3.
// while(!feof(fp))printf("%c",fgetc(fp));
// while((ch=getchar())!='#')
// {
// fputc(ch,fp);
// }
zhushi(str);
enter(str);
deblank(str);
// fclose(fp);
}
FILE *fpp;
fpp=fopen("D:\\app\\vscode\\codes\\compilation\\exp1-2.txt","w");
if(fpp==NULL)
{
printf("fail to open the file!\n");
exit(0);
}
else
{
// printf("The file is open!\n");
fputs(str,fpp);
fclose(fpp);
fclose(fp);
}
FILE *file;
file = fopen("D:\\app\\vscode\\codes\\compilation\\exp1-3.txt","w");
fclose(file);
cffx();
printf("处理完成\n");
system("pause");
return 0;
}
运行结果:
例子:
/main/
if(a>3)
{
a–;//a>3
}
控制台:
文档一(源代码):
文档二(预处理之后的代码):
文档三(二元组):
好了,结束,如果不需要中间结果文档二,可以直接注释掉。
边栏推荐
- Comparaison des solutions pour la plate - forme mobile Qualcomm & MTK & Kirin USB 3.0
- Postman 中级使用教程【环境变量、测试脚本、断言、接口文档等】
- Feature of sklearn_ extraction. text. CountVectorizer / TfidVectorizer
- [golang] leetcode intermediate - fill in the next right node pointer of each node & the k-smallest element in the binary search tree
- Whistle+switchyomega configure web proxy
- Walk into WPF's drawing Bing Dwen Dwen
- Keyword inline (inline function) usage analysis [C language]
- Pytorch: tensor operation (I) contiguous
- A possible cause and solution of "stuck" main thread of RT thread
- ES6 grammar summary -- Part 2 (advanced part es6~es11)
猜你喜欢

JS function promotion and declaration promotion of VaR variable

MP3mini播放模块arduino<DFRobotDFPlayerMini.h>函数详解

Postman 中级使用教程【环境变量、测试脚本、断言、接口文档等】
![Several declarations about pointers [C language]](/img/9b/ace0abbd1956123a945a98680b1e86.png)
Several declarations about pointers [C language]
![Intermediate use tutorial of postman [environment variables, test scripts, assertions, interface documents, etc.]](/img/b0/176bf6dea2201afc892d6750c5974b.png)
Intermediate use tutorial of postman [environment variables, test scripts, assertions, interface documents, etc.]

Time slice polling scheduling of RT thread threads

JS正则表达式基础知识学习

ESP8266连接onenet(旧版MQTT方式)

Amba, ahb, APB, Axi Understanding

Basic operations of databases and tables ----- creating data tables
随机推荐
小天才电话手表 Z3工作原理
Important methods of array and string
单片机蓝牙无线烧录
vim命令行笔记
. elf . map . list . Hex file
Walk into WPF's drawing Bing Dwen Dwen
记一次云服务器被密码爆破的经历——关小黑屋、改密码、改端口
map文件粗略分析
Who says that PT online schema change does not lock the table, or deadlock
VIM command line notes
GCC compilation options
NRF24L01故障排查
MP3mini播放模块arduino<DFRobotDFPlayerMini.h>函数详解
js题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
Variable parameter principle of C language function: VA_ start、va_ Arg and VA_ end
MySQL time, time zone, auto fill 0
OSPF message details - LSA overview
About using @controller in gateway
ARM PC=PC+8 最便于理解的阐述
Kaggle competition two Sigma connect: rental listing inquiries (xgboost)