编译原理——词法分析程序c语言实现完整版
词法分析程序
一、实验目的
根据所学知识设计、编制并调试一个词法分析程序,加深对词法分析概念的理解以及编写代码的锻炼。
二、实验内容
(1)分组完成,每组由3-4位同学组成
(2)确定源语言L和编写程序的语言P
(3)用正规式描述L的词法规则
(4)根据正规式构造给出识别单词的DFA M
(5)根据M,用语言P编写L的词法分析程序
三、实验过程
首先,本实验使用的C++语言编写分析C语言的词法分析程序,基本功能为识别以下几类单词:
标识符
关键字
运算符
界符
常数
注释
1. 文法设计
给出各类单词的词法规则描述(正则文法或正则表达式)
-
1.标识符:(A|B|…|Z|a|b|…|z|
)( A|B|…|Z|a|b|…|z|
| 0|1|2|…|9)* - 2.关键字:auto | break | case | char | const | continue | default | do | double | else | enum | extern | float | for | goto | if | int | long | register | return | short | signed | sizeof | static | struct | switch | typedef | unsigned | union | void | volatitle | while
- 3.运算符:+ | – | * | / | % | ++ | += | – | -> | -= | *= | /= | %= | = | == | != | > | < | >= | <= | ! | && | || | & | | | ~
- 4.界符:( | ) | [ | ] | { | } | , | : | ; | ” | ’
-
5.常数:(0|1|2|…|9)(0|1|2|…|9)
(( . (0|1|2|…|9) (0|1|2|…|9)
)|ε)
2. 构造DFA
3. 种别编码
词法分析需要输出单词符号对应的属性值,因此构造出如图1-2所示的种别编码表,分别为:
- 关键字:一符一种
- 其他字符:一符一种
- 运算符:一符一种
- 界符:一符一种
- 数字:统一使用200
-
标识符:统一使用300
4.各函数功能说明
6. 主程序功能流程图
四、测试截图
本次分析为使用了c语言的一个完整的程序输入进入记事本,并用程序进行读文件,文件中的程序截图如图4-1所示。
五、程序源代码(你们最喜欢的!喜欢记得住转发点赞啊)
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctype.h>
#include <stdlib.h>
#define _KEY_WORD_END " "
using namespace std;
typedef struct {
/* 单词二元式的结构 */
int value; /* 种别码 */
string token; /* 存放单词的字符串 */
} Word;
vector<string> idQueue; //标识符容器,为了保证标识符不重复
Word* scanner(FILE *fp); // 对文件扫描读取
int keyOrIdentifier(string token); //判断是关键字还是标识符
bool isIdExit(vector<string> idQueue,string id); //对标识符序列进行扫描
string KeyWords[]= {
"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register","return","short","signed",
"sizeof","static","struct","switch","typedef","unsigned","union","void","volatitle","while",_KEY_WORD_END};
int line_num=1;
/*
输入:源程序字符串
输出:二元式<value,token>
*/
int main() {
Word* oneword=new Word;
FILE *fp;
int over=1; //如果词法解析出现错误,则结束读取
if( (fp=fopen("input.txt","rt")) == NULL ) {
cout<<"Cannot open file, press any key to exit!"<<endl;
}
while(over<1000&&over!=-1) {
oneword=scanner(fp);
if(oneword->value<1000&&oneword->value>0)
cout<<"<"<<oneword->value<<","<<oneword->token<<">"<<endl;
over=oneword->value;
}
fclose(fp);
system("pause");
return 0;
}
/* 判断是标识符还是关键字*/
int keyOrIdentifier(string token) {
int i=0;
while(KeyWords[i]!=_KEY_WORD_END) {
if(KeyWords[i]==token) {
return i+1;
}
i=i+1;
}
return 300;
}
/*判断标识符是否重复*/
bool isIdExit(string id) {
vector<string>::iterator iter=find(idQueue.begin(),idQueue.end(),id);
if(iter==idQueue.end()) {
return false;
}
return true;
}
/*扫描程序*/
Word* scanner(FILE *fp) {
char ch;
string token="";
Word
版权声明:本文为qq_43371778原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。