您的位置:首页 > 其它

词法分析器

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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息