C语言实现简单词法分析器(if-else)
为进一步熟悉编译原理中词法分析的实现过程,采用c语言实现一个简单的针对c语言的词法分析器。此程序只能分析合法c语言代码段并生成token序列,无法进行预处理或错误识别。
已知的问题
- 只能识别存储于.txt文件中的代码片段,且文件的最后一个字符必须为‘\n’
- 只实现了对文件的绝对路径寻址,以相对路径方式寻址没有找到生成文件
详细代码
//c语言实现简易词法分析程序
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
/*共有如下六类字符表
第一类:标识符(iT) (_ | a~z | A~Z)(_ | a~z | A~Z | 0~9)*
第二类:常数(CT) (1~9)(0~9)*| 0(0~7)* | 0x(0~9 | a~f| A~F)+
第三类:关键字(kT)(32) 独立定义
第四类:界符与运算符(pT) 独立定义
第五类:字符(cT) '(o_letter | \(s_letter | x(0)*(digit | 空)(digit | 空)(digit | 空) | (0~7 | 空)(0~7 | 空)(0~7 | 空)))'
第六类: 字符串(sT) "(字符 | digit)*"
*/
/*——————————————————程序开始——————————————————*/
//全局文件流、token缓存、字符缓存
fstream in, out;
string token;
char tmp;
//关键字表
static char kT[32][20] = {
"auto", "double", "int", "struct", "break", "else",
"long", "switch", "case", "enum", "register", "typedef",
"char", "extern", "return", "union", "const", "float",
"short", "unsigned", "continue", "for", "signed", "void",
"defualt", "goto", "sizeof", "volatile", "do", "while",
"static", "if"
};
//界符运算符表
static char pT[43][10] = {
"+", "+=", "++", "-", "-=", "--", "*", "*=", "/", "/=",
"<", "<=", ">", ">=", "=", "==", "!", "!=", "&", "&&",
"|", "||", "%", "%=", "<<", ">>", "->", "[", "]", "{",
"}", ".", "\?", ":", "{", "}", ";", "(", ")", "^",
",", "#", "~"
};
vector<string> cT;//字符数组,包含单引号
vector<string> sT;//字符串数组,包含双引号
vector<string> iT;//标识符表
vector<double> CT;//常数表
//判定函数
bool is_atoZ(char ch){
if((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
return true;
else
return false;
}
bool is_1to9(char ch){
if(ch >= '1' && ch <= '9')
return true;
else
return false;
}
bool is_0to9(char ch){
if(ch >= '0' && ch <= '9')
return true;
else
return false;
}
bool is_1to7(char ch){
if(ch >= '1' && ch <= '7')
return true;
else
return false;
}
bool is_0to7(char ch){
if(ch >= '0' && ch <= '7')
return true;
else
return false;
}
bool is_num_of_0x(char ch){
if((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'))
return true;
else
return false;
}
bool is_num_of_0x_nz(char ch){
if((ch >= '1' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'))
return true;
else
return false;
}
bool is_none(char ch){
if(ch == ' ' || ch == '\n' || ch == '\t')
return true;
else
return false;
}
//情况判定
int get_case(char c){
if(is_atoZ(c))
return 2;//转至iT/kT
else if(is_0to9(c))
return 5;//转至CT
else if(is_none(c))
return 8;//转至空白处理
else if(c == '_')
return 1;//转至iT
else if(c == '/')
return 3;//转至注释
else if(c == '0')
return 4;//转至8/16进制
else if(c == '\'')
return 6;//转至cT
else if(c == '\"')
return 7;//转至sT
else
return 9;//转至pT查表
}
//具体处理
void get_iT(void){
bool flag = true;
token += tmp;
while(!in.eof()){
tmp = in.get();
if(is_atoZ(tmp) || is_0to9(tmp) || tmp == '_')
token += tmp;
else
break;
}
in.seekg(-1