这是我自己的第一篇博客,就分享一下最近才做完的编译原理实验,词法分析器。
本次实验中我用MYSQL数据库存储自动机状态表,这样做的目的只是为了在后续的课设中可以继续使用现在的代码。这一段代码并不是太完善,发出来只是为了太完善。里面还有很多问题,比如对字符和字符串的识别,不知道为什么数据库无法将‘和“转换到我制定的ch_code,但是我的改进方法是将char字符转为ASCLL码,再将ASCLL码转换为ch_code.
这也是我第一次使用数据库,这个版本的代码只是初始代码,里面有诸多不足,还望赐教。我正在改写该代码,将会用更美的方式完成。
#include "stdafx.h"
#include<algorithm>
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;
}
if (ch_code != 99)
end_state = state_check(state, ch_code);
else
end_state = 0;
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
{
if (mysql_query(&mysql, sql))
{
return 99;
}
else
{
result = mysql_store_result(&mysql);
if (mysql_num_rows(result) != NULL)
{
MYSQL_ROW row;
while (row = mysql_fetch_row(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
{
if (mysql_query(&mysql, sql))
{
return -1;
}
else
{
result = mysql_store_result(&mysql);
if (mysql_num_rows(result) != NULL)
{
MYSQL_ROW row;
while (row = mysql_fetch_row(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;
}
#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);
int state_to_code(int state_before, list<char> token);
void print(int code, list<char> token);
cout << "< " << code << " , ";
for (it = token.begin();it != token.end();++it)
{
cout << *it;
}
cout << " >"<<endl;
}
#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)
token.push_back(ch);
else
{
if (state == -1)
{
state_before = 1;
if (token.size() != 0)
{
code = state_to_code(state_before, token);
print(code, token);
token.clear();
token.push_back(ch);
}
state = state_change(state, ch);
}
else
{
state = 1;
}
if (token.size() != 0)
{
code = state_to_code(state_before, token);
print(code, token);
t`
``
ken.clear();
}
}
}
return 0;