C语言词法分析器--编译原理

C语言词法分析器

这是老师布置的编译原理的实验课任务,课余时间花了近一个星期的时间去编写代码(主要是C++太久没有用了,好多函数都不熟悉,查阅了很多资料),这次的词法分析只有简单的语法错误判断功能,约等于没有.如果想要增加功能可以在相关函数代码段增加即可.
而且token的种别码只做了粗略的区分,想要加上也很简单

c语言词法分析流程如图所示:
在这里插入图片描述

代码如下:这次的代码算是我对代码整洁之道前期知识的一个练习,特别是变量的命名以及函数的编写,如果觉得写的不错可以看看我关于代码整洁之道的相关文章

这次的代码基本没有写注释,但是我相信大家结合流程图也能看懂,如果觉得太长可以将代码复制到visual studio中将函数代码块闭合起来这样看起来就逻辑清楚了

#include <iostream>
#include <string>
#include <map>
#include <ctype.h>
#include <algorithm>
using namespace std;
string readFile(string fileName);
string fileFilter();
string singleLineCommentsFilter();
string multilineCommmentsFileter();
string specialCharacterFilter();
void separateAndJudge();
bool isReservedWord(string vocabulary);
void separateAndJudge();
void showTokenData();
int digitStarted(int cnt);
bool isBoundSymbol(char ch);
bool isOperator(char ch);
int judgeStartingCharactorType(char ch);
bool isDigit(char ch);
bool isAlpha(char ch);
int alphaStarted(int cnt);
int underlineStarted(int cnt);
string transCharToString(char ch);
int operatorStarted(int cnt);
string codeSource;
map<string, int> tokens;//identifier is 1,reservedWord 2,digit 3,borderSymbol 4,operator 5
int main()
{
   
	codeSource = readFile("d:\\testCode.txt");
	cout << "This is source code" << endl << "---------------------------------" << endl << endl;
	cout << codeSource << endl;

	cout << "This is code filtered" << endl << "---------------------------------" << endl;
	codeSource = fileFilter();
	cout << codeSource << endl;
	cout << "-----------------------" << endl;


	separateAndJudge();

	cout << "this is tokens " << endl;
	cout << "-----------------------" << endl;
	showTokenData();
	return 0;
}


string readFile(string fileName)
{
   
	FILE* fp;
	if ((fp = fopen(fileName.c_str(), "r")) == NULL)
	{
   
		cout << "cant open file";
		exit(0);
	}
	else
	{
   
		string codeSource;
		char ch;
		while ((ch = fgetc(fp)) != EOF)
		{
   
			codeSource += ch
  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言词法分析器编译器的一个重要组成部分,它的作用是将源代码转换为单词流(Token Stream),为后续的语法分析提供基础。下面是一个简单的C语言词法分析器的实现过程: 1. 定义单词类型 在C语言中,有很多种类型的单词,例如关键字、标识符、常量、运算符等。我们需要先定义这些单词的类型,例如: ```c typedef enum { KEYWORD, // 关键字 IDENTIFIER, // 标识符 CONSTANT, // 常量 OPERATOR, // 运算符 DELIMITER // 分隔符 } TokenType; ``` 2. 定义单词结构体 定义单词结构体,包含单词的类型和值: ```c typedef struct { TokenType type; // 单词类型 char* value; // 单词值 } Token; ``` 3. 实现词法分析器 词法分析器的主要任务是将源代码转换为单词流。我们可以使用有限状态自动机(Finite State Automaton)来实现词法分析器。具体实现过程如下: - 读取源代码字符流 - 根据字符流的内容,判断当前状态 - 根据当前状态和读取的字符,转换到下一个状态 - 如果当前状态是单词的结束状态,则生成一个单词,并将其加入单词流中 下面是一个简单的词法分析器的实现代码: ```c Token* getNextToken(char* sourceCode) { int state = 0; // 当前状态 char* value = ""; // 单词值 TokenType type; // 单词类型 while (*sourceCode != '\0') { char c = *sourceCode; switch (state) { case 0: if (isalpha(c)) { state = 1; value = appendChar(value, c); } else if (isdigit(c)) { state = 2; value = appendChar(value, c); } else if (c == '+' || c == '-') { state = 3; value = appendChar(value, c); } else if (c == '*' || c == '/') { state = 4; value = appendChar(value, c); } else if (c == '(' || c == ')' || c == '{' || c == '}' || c == ';' || c == ',') { state = 5; value = appendChar(value, c); } else if (c == '=') { state = 6; value = appendChar(value, c); } else if (c == '<' || c == '>') { state = 7; value = appendChar(value, c); } else if (c == '!') { state = 8; value = appendChar(value, c); } else if (c == ' ' || c == '\n' || c == '\t') { // 忽略空格、换行和制表符 } else { printf("Error: invalid character\n"); exit(1); } break; case 1: if (isalnum(c)) { value = appendChar(value, c); } else { type = getKeywordType(value); if (type == IDENTIFIER) { type = IDENTIFIER; } return createToken(type, value); } break; case 2: if (isdigit(c)) { value = appendChar(value, c); } else { return createToken(CONSTANT, value); } break; case 3: if (c == '+' || c == '-') { value = appendChar(value, c); } else { return createToken(OPERATOR, value); } break; case 4: return createToken(OPERATOR, value); case 5: return createToken(DELIMITER, value); case 6: if (c == '=') { value = appendChar(value, c); return createToken(OPERATOR, value); } else { return createToken(OPERATOR, value); } break; case 7: if (c == '=') { value = appendChar(value, c); return createToken(OPERATOR, value); } else { return createToken(OPERATOR, value); } break; case 8: if (c == '=') { value = appendChar(value, c); return createToken(OPERATOR, value); } else { printf("Error: invalid character\n"); exit(1); } break; } sourceCode++; } return NULL; } ``` 4. 测试词法分析器 编写一个测试程序,读取源代码文件,调用词法分析器,输出单词流。 ```c int main() { char* sourceCode = readFile("source.c"); Token* token; while ((token = getNextToken(sourceCode)) != NULL) { printf("%s\t%s\n", getTokenTypeString(token->type), token->value); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值