《编译原理》陈火旺——词法分析程序c语言实现完整版

  • Post author:
  • Post category:其他




编译原理——词法分析程序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 版权协议,转载请附上原文出处链接和本声明。