手撸词法分析器(C/C++)
- 一.背景
- 二.什么是词法分析器?
- 三.代码
- 四.思考
一.背景
这学期开设了编译原理,要求写个基本的词法分析器。所以博主就自己写了一份代码,也比较简单基础。
二.什么是词法分析器?
简单来说就是能识别基本的符号(+,-,*,/,),关键词(for ,while,return ,int ),数字等。这么说大家应该有个基本了解,那么我们如何写代码呢,这里有个思维图。
可以大致将单词分成这几类,然后进行判断即可。
三.代码
#include <stdio.h>
#include <string>
#include < fstream >
#include <iostream>
int scan_word(char* buff);
using namespace std;
char buf[102400] = { 0 };
char key[][20] = {"if","else","for","while","do","return","break","continue",
",",";","{","}","(",")",
"+","-","*","/",
"<","<=","=",">=","< ","*=","/=","+=","-=","++",
"int", "char", "float","double","unsigned char","unsigned int","void",
"main"
};int main()
{ ifstream fin;int i =0,j=0,k=0;fin.open("demo.txt", ios::in);char temp[20] = { 0 };if (!fin.is_open()){cout << "读取文件失败" << endl;return 1;}while ((buf[i++] = fin.get()) != EOF);buf[i] = '\0';while (j < i-2){ start:if (buf[j] == 0x0a || buf[j] == 0x0d || isspace(buf[j])){j++;goto start;}//字母else if ((buf[j] >= 65 && buf[j] <= 90) || (buf[j] >= 97 && buf[j] <= 122)){while ((buf[j] >= 65 && buf[j] <= 90) || (buf[j] >= 97 && buf[j] <= 122)|| ((buf[j] >= 48 && buf[j] <= 57))||buf[j]==95){temp[k++] = buf[j++];} temp[k] = '\0';k = 0;scan_word(temp);}//数字else if ((buf[j] >= 48 && buf[j] <= 57)){while (buf[j] >= 48 && buf[j] <= 57){temp[k++] = buf[j];j++;}if (buf[j] == '.'){temp[k++] = buf[j];j++;}while (buf[j] >= 48 && buf[j] <= 57){temp[k++] = buf[j];j++;}temp[k] = '\0';k = 0;printf("\(51,\"\%s\"\)\n", temp);//scan_word(temp);}//其他符号else { if(buf[j]=='>'||buf[j]=='='||buf[j]=='<' || buf[j] == '+'|| buf[j] == '-' || buf[j] == '*'||buf[j] == '/'){if (buf[j + 1] == '='){temp[0] = buf[j++];temp[1] = buf[j++];temp[2] = '\0';}if (buf[j + 1] == '+'){temp[0] = buf[j++];temp[1] = buf[j++];temp[2] = '\0';}else goto end;}else{ end:temp[0] = buf[j++];temp[1] = '\0';}scan_word(temp);}}}
int scan_word(char *buff)
{ for (int i = 0; i < 31; i++){if (strcmp(buff, key[i]) == 0){ printf("\(%d,\"\%s\"\)\n",i,buff); return 1;}}printf("\(50,\"\%s\"\)\n", buff);return 0;
}
四.思考
这只是一个简单的词法分析器,很多功能都不完善,你们也可以自己添加代码改善一下。