词法分析器

这是我自己的第一篇博客,就分享一下最近才做完的编译原理实验,词法分析器。
本次实验中我用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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值