Compiler_词法分析_表驱动法_分析文件

来源:互联网 发布:视频生成二维码软件 编辑:程序博客网 时间:2024/05/17 22:50

本文出自:http://blog.csdn.net/svitter


一开始做这个实验真是觉得各种简单- -就是一张状态转换图不停的跳来跳去。。后来发现我太天真了。。一个搞来搞去搞不清楚的bug是因为老师给的状态转换图坑了 - - 当然这肯定不怪老师因为我一开始做的时候居然没发现= =。

状态转换图我就暂且不贴了,另外两篇文章的地址如下:

Compiler_词法分析_表驱动法

Compiler_词法分析_直接转向法

这次的是分析文件,用双缓冲。其实我也不是很清楚自己到底有没有用上双缓冲。。

下面简单介绍一下我所理解的双缓冲:

1.我理解的双缓冲区,其实就是一个缓冲区分了两部分的,前半部分用于分析,后半部分用于暂存。

2.分析部分分析完以后,下一次分析的时候,暂存部分作为新的分析部分,分析部分作为暂存部分。

3.如果整个单词超出了分析部分,暂存部分,那么就存入文件或者其他数组,再做处理。

另外,请教老师得知,一般要求缓冲长度大于单词长度。


介绍就这么多吧,下面贴一下代码:

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>using namespace std;#define MIDBUFFER 1023#define WHOLEBUFFER 2048#define MAXWORD 10000//Double bufferstruct bibuffer{char *buffer;            //缓冲区空间char *forward;                 //后向指针int count;                   //前向指针记数int state;//当前的状态};//lexical analysis//schemeint State[8][5];//set final statusconst bool Acstatus[7] ={ 0, 1, 1, 0, 0, 1, 0};//for JudgeNumint JudgeNum(char &ch){if (ch >= '0' && ch <= '9')return 0;else if (ch == '.')return 1;else if (ch == 'E')return 2;else if (ch == '+' || ch == '-')return 3;elsereturn 4;}//initial the schemevoid init(){//set error statefor (int i = 0; i < 8; i++)for (int j = 0; j < 5; j++){State[i][j] = 7;}//set tableState[0][0] = 1;State[0][1] = 6;State[1][0] = 1;State[1][1] = 2;State[1][2] = 5;State[2][0] = 2;State[2][2] = 3;State[3][3] = 4;State[4][0] = 5;State[5][0] = 5;State[6][0] = 2;}//parse, change state due to char;void parse(int &state, char &ch, char *cur){state = State[state][JudgeNum(ch)];if (state != 7)//可以在此考虑拼接问题*cur = ch;}bool FinalState(int &state){return state == 7;}void InitBuff(bibuffer *bbuf, FILE *fp, char *buffer){fread(buffer, MIDBUFFER, 1, fp);//first bufferbuffer[MIDBUFFER] = EOF;    //put the endfread(buffer + MIDBUFFER + 1, MIDBUFFER, 1, fp);//next bufferbuffer[WHOLEBUFFER - 1] = EOF;    //put the end    bbuf->buffer = buffer;bbuf->forward = bbuf->buffer;bbuf->count = 0;bbuf->state = 0;}void pause(){}//void Analysis( FILE *fp){    int i;bibuffer *bbuf;char *temp, *buffer;        //用于记录当前的位置bool init = false;    bbuf = new bibuffer();    temp = new char[MAXWORD];    buffer= new char[MAXWORD];    i = 0;    memset(temp, '\0', MAXWORD);while (1){if(!init)        {InitBuff(bbuf, fp, buffer);init = true;}if(*(bbuf->forward) == '1')pause();//count值位于第一缓冲区或者第二缓冲区中if ((bbuf->count < MIDBUFFER || ((bbuf->count > MIDBUFFER) && (bbuf->count < WHOLEBUFFER)))&& !FinalState(bbuf->state)){//parse state, charbbuf->state = State[bbuf->state][JudgeNum(*(bbuf->forward))];            if (bbuf->state != 7)//可以在此考虑拼接问题                temp[i] = *(bbuf->forward);            i++;bbuf->forward++;bbuf->count++;}//count值超出第一缓冲区else if (bbuf->count == MIDBUFFER && !FinalState(bbuf->state)){//read next bufferfread((bbuf->buffer) + MIDBUFFER + 1, MIDBUFFER, 1, fp);            bbuf->forward++;bbuf->count++;            bbuf->state = State[bbuf->state][JudgeNum(*(bbuf->forward))];            if (bbuf->state != 7)//可以在此考虑拼接问题                temp[i] = *(bbuf->forward);            i++;}//count值超出第二缓冲区else if (bbuf->count >= WHOLEBUFFER && !FinalState(bbuf->state)){//read first bufferfread((bbuf->buffer) + MIDBUFFER + 1, MIDBUFFER, 1, fp);            bbuf->forward = bbuf->buffer;bbuf->count = 0;            bbuf->state = State[bbuf->state][JudgeNum(*(bbuf->forward))];            if (bbuf->state != 7)//可以在此考虑拼接问题                temp[i] = *(bbuf->forward);            i++;}//识别出一个单词else if (FinalState(bbuf->state))//当一个终态出现{if (temp[0] != '\0')printf("%s ", temp);memset(temp, '\0', MAXWORD);i = 0;bbuf->state = 0;//count 不用改变}if (bbuf->count != MIDBUFFER && bbuf->count < WHOLEBUFFER&& *(bbuf->forward) == EOF){break; //analysis end}}delete temp;delete bbuf;delete buffer;}int main(){//Declare the variablesFILE *fp;fp = fopen("test.txt", "rt");//initialinit();Analysis(fp);return 0;}

本来想要做成每次调用返回一个单词的。但是发现我去每次调用返回一个单词怎么做到最长匹配等等诸多问题。

肯定能实验但肯定不是老师所要求的,被虐了这么多天也就没有心思再继续写下去了。

心得:

中间出现了很多问题。比如中间识别后的重置,判断顺序的先后,一点一点DEBUG出来的。pause()函数是为了调试特意添加的,对于程序效率肯定有影响,但是觉得还是不错的一个调试方法,就暂且保留了。用于测试的test:

1.255dsfasfsafsafdasfdsafasdfdsfasdsfasfsaf554.54fdsafasdfdsfaserqewrewqr1.2E+2sdgfdsakfshak2313dslkhalfkakjrege1d

略微有些随意,也算是够用了吧。。对于“1.”这样的数字也是可以识别的。

之前先写好了跳转的状态转换表用处是很大的。。但是难免也会出现小BUG慢慢的找上去调好了。也考虑如果有时间可以做一下语法分析那些部分。有BUG慢慢调,慢慢整理思路思密达。。。

还有WEB作业和JSP作业。大二下学期真是人间小炼狱啊。。。。


By Svitter。

0 0