双缓冲区

                                                                          双缓冲区
                                                                                                                                                作者:周顺利

       在一个模式被匹配之前,词法分析器往往需要超前扫描该词素后面的若干个字符,使用将字符退回输入流的方法,需要移动大量字符的时间,由于 词法分析器是编译期间唯一需要逐一扫描源程序字符的过程,因此它的效率将极大的影响编译器的性能,因此人们发明了双缓冲区的技术。
    双缓冲区技术原理如下:
    把一个缓冲区分成前后两个部分,每部分能够容纳N(1024/4096)个字符,每次系统读命令读入N个字符到前半部分或者后半部分,如果剩余的不足N个字符,则在最后增加一个不同于其他任何字符的字符,如eof/#,用于标识源文件的结束。缓冲区包括两个指针beginning和forward,在两个指针之间的字符串就是当前的词素。一开始两个指针都指向第一个字符,然后forward向后扫描,直至发现一个匹配的词素为止。如果forward跨过中间标记,则往后半部分读入N个字符。如果forward指针移过最后位置,则向前半部分读入N个字符,且forward指针重新指向开始继续处理过程。为了处理方便在两个部分的最后都增加一个文件结束标识eof。示意图如下:
 ______________________________________________________________________
|............for......while.... ........................................ |....int i ..................................................    ...................| |_______________________________eof|_______________eof________________eof|
                                              |                                                   | 
                                      beginning                                    forward

   下面是双缓冲区的一个c实现:

#include <stdio.h>
#include <string.h>

#define MAXWORD 1000
 
struct bibuffer
{
 char* buffer[2048];            //缓冲区空间
 char* beginning,forward;     //前向和后向指针
 int count;                   //前向指针记数
} bbuf;

void parse(char c)
{
 if(c=' ')
 {
  memcpy(word[i],beginning,(size_t)(forward-beginning));
  i++;
 }
 else forward++;
}

int main(int argc,char* argv)
{
 File* fp;
 char* word[MAXWORD];
 int i=0;
 buffer=new char[2048];
 fp=open("test.c","r");
 read(fp,buffer,1023);
 buffer[1023]='#';
 read(fp,buffer+1024,1023);
 buffer[2047]='#';
 bbuf->buffer=buffer;
 bbuf->beginning=bbuf->forward=bbuf->buffer;
 bbuf->count=0;
 while(1)
 {
  forward=forward+1;
  if(count==1023)
  {
   read(fp,buffer+1024,1023);
   forward++;
   //这个函数的具体代码就要和具体的词法分析规则而定,这里假设只识别空格分割的单词
   parse(*forward);
  }
  else if(count>=2048)
  {
   read(fp,buffer,1023);
   forward=bbuf->buffer;
                        //这个函数的具体代码就要和具体的词法分析规则而定,这里假设只识别空格分割的单词
   parse(*forward);
  }
  else if(count!=1023&&count<2048&&(*forward)='#')
  {
   break;           //词法分析结束
  }
 } 
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值