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

本文档详细介绍了使用C++语言编写的词法分析程序,旨在加深对词法分析概念的理解。程序能识别标识符、关键字、运算符、界符、常数和注释等C语言元素,通过文法设计、DFA构造和种别编码实现。附带了程序源代码和测试截图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编译原理——词法分析程序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* ReadWord=new Word;
	ReadWord->value=0;
	ReadWord->token="";

	ch=fgetc(fp);

	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值