词法分析器
2015-11-05 21:29
239 查看
这是我自己的第一篇博客,就分享一下最近才做完的编译原理实验,词法分析器。 本次实验中我用MYSQL数据库存储自动机状态表,这样做的目的只是为了在后续的课设中可以继续使用现在的代码。这一段代码并不是太完善,发出来只是为了太完善。里面还有很多问题,比如对字符和字符串的识别,不知道为什么数据库无法将‘和“转换到我制定的ch_code,但是我的改进方法是将char字符转为ASCLL码,再将ASCLL码转换为ch_code. 这也是我第一次使用数据库,这个版本的代码只是初始代码,里面有诸多不足,还望赐教。我正在改写该代码,将会用更美的方式完成。
// stdafx.cpp : 只包括标准包含文件的源文件 // ConsoleApplication2.pch 将作为预编译头 // stdafx.obj 将包含预编译类型信息 #include "stdafx.h" #include<algorithm> // TODO: 在 STDAFX.H 中引用任何所需的附加头文件, //而不是在此文件中引用 int state_change(int state, char ch) { int end_state = 0; int ch_code; if (ch != '\n') { ch_code = ch_to_num(ch); } else { ch_code = 99; } //(ch_code > last_num) ? ch_code = last_num + 1; if (ch_code != 99) end_state = state_check(state, ch_code); else end_state = 0; /*if (state >= 1 && state <= LAST_STATE) { end_state = state_check(state, ch_code); }*/ return end_state; } int ch_to_num(char ch) { int ch_code; MYSQL mysql; MYSQL_RES * result; char chtmp[4] = {'\'', ch,'\'' }; char sql[200] = "select * from char2num where current_char="; strcat_s(sql, sizeof(sql), chtmp); mysql_init(&mysql); if (!mysql_real_connect(&mysql, "localhost", "root", "1234", "state", 0, NULL, 0)) { printf_s("Can not connect stateable"); } else { //printf_s("connect stateable"); if (mysql_query(&mysql, sql)) { //printf_s("query failed!"); return 99; } else { result = mysql_store_result(&mysql); if (mysql_num_rows(result) != NULL) { MYSQL_ROW row; while (row = mysql_fetch_row(result)) { /** * MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); * 检索行 */ ch_code = atoi(row[1]); } } mysql_free_result(result); } } mysql_close(&mysql); if (ch_code < 0) return 99; else return ch_code; } int state_check(int state, int ch_code) { MYSQL mysql; MYSQL_RES * result; char statetmp[4]; char ch_codetmp[4]; char sql[200] = "select * from statetable where current_state="; char * code = " and ch_code="; _itoa_s(state, statetmp, 4, 10); _itoa_s(ch_code, ch_codetmp, 4, 10); strcat_s(sql, sizeof(sql), statetmp); strcat_s(sql, sizeof(sql), code); strcat_s(sql, sizeof(sql), ch_codetmp); int next_state; mysql_init(&mysql); if (!mysql_real_connect(&mysql, "localhost", "root", "1234", "state", 0, NULL, 0)) { printf_s("Can not connect stateable"); } else { //printf_s("connect stateable"); if (mysql_query(&mysql, sql)) { //printf_s("query failed!"); return -1; } else { result = mysql_store_result(&mysql); if (mysql_num_rows(result) != NULL) { MYSQL_ROW row; while (row = mysql_fetch_row(result)) { /** * MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); * 检索行 */ next_state = atoi(row[2]); } } } mysql_free_result(result); } mysql_close(& mysql); if (next_state < 0) return -1; else return next_state; } int state_to_code(int state_before, list<char> token) { int code; string str(token.begin(), token.end()); list<string> ::iterator it = find(KT.begin(), KT.end(),str ); switch (state_before) { case 2: if (it != KT.end()) { code = 1; } else { code = 2; } break; case 3:code = 3;break; case 24:code = 4;break; case 25:code = 5;break; case 26:code = 26;break; default:code = 7;break; } return code; } void print(int code, list<char> token) { list<char>::iterator it; string str(token.begin(), token.end()); cout << "< " << code << " , "; for (it = token.begin();it != token.end();++it) { cout << *it; } cout << " >"<<endl; } //void parse(int code) //{ // //}
//stdafx.h #include "targetver.h" #include <stdio.h> #include <tchar.h> #include<list> #include<iostream> #include "stdafx.h" #include <windows.h> #include"C:\\Program Files\MySQL\MySQL Server 5.6\include\mysql.h" #pragma comment(lib,"libmysql") using namespace std; int LAST_STATE = 1000; int last_num = 20; //关键字,界定符 list<string> KT={ "int","main","void","if","else","char"}; list<string> PT={ ">=","<=", "==", "=",">","<","+","-","*","/","{","}",",",";","(",")" }; //方法声明 void initstate(void); int state_change(int state, char ch); int ch_to_num(char ch); int state_check(int state, int ch_code); //void reset(FILE *fp, list<char> token,int state); int state_to_code(int state_before, list<char> token); void print(int code, list<char> token); //votr(token.begin(), token.end()); cout << "< " << code << " , "; for (it = token.begin();it != token.end();++it) { cout << *it; } cout << " >"<<endl; } //void parse(int code) //{ // //}
//主程序 #include "stdafx.h" list<char> token; int main() { int state_before; int state = 1;//设置初始状态 char ch; int code; FILE *fp; fopen_s(&fp,"test.txt","r"); while ((ch = getc(fp)) != '#')//读取字符 { state_before = state;//存储自动机状态 state = state_change(state, ch);//自动机状态转换 if (state>0)//state==0:终止状态;state>0:非终结状态;state==-1:当前字符为界符;state的值只能返回大于等于-1的整数;详见stdafx.cpp/int state_change( int state,char ch) token.push_back(ch);//非终结时存入字符名,形成Token序列 else { if (state == -1)//表明当前字符不是非终结符,同时不是终结符,而是界符接其它标识符或者变量名,亦或是标识符(变量名)接界符 { state_before = 1;//前一个token序列至此应当结束,下一个token序列在这里开始,可以理解为当前字符已经从开始状态跳转完成 if (token.size() != 0)//token序列的长度如果为0则表示当前当前字符为空 { code = state_to_code(state_before, token);//生成Token类别码 print(code, token);//输出<类别码,token序列> token.clear();//清空当前token序列,为下一个token序列初始化 token.push_back(ch);//形成一个新的序列 } state = state_change(state, ch); } else { state = 1;//初始化 } if (token.size() != 0) { code = state_to_code(state_before, token);//生成Token类别码 print(code, token); //parse(code);//使用Token类别码 t` `` ken.clear(); } } } return 0;