⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cpp

📁 近日学习编译原理课程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include "parser.h"
#include <io.h>
#include <malloc.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

char sourcefile[FILENAME_LENGTH];
FILE *in = (FILE *) 0, *out = (FILE *) 0;
FILE *str=(FILE*)0;

//至命错误--退出
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 2
#endif

void fatal_error( const char msg[] ){
	fprintf( stderr, "%s\n", msg );
	exit( EXIT_FAILURE );
}

void   local_init();
void   local_end();

static int _stdcall act_identity(char&c);
static int _stdcall act_comment2(char&c);
static int _stdcall act_string(char&c);
static int _stdcall act_comment1(char&c);
static int _stdcall act_chinese(char&c);
static int _stdcall act_number(char&c,int state);
static void *flex_alloc ( unsigned int );
static void *flex_realloc ( void *, unsigned int );
static void flex_free ( void * );


static TUPLE result_tuple;
static int linenum=1;
static int stringpos;
static int init = 1;

#ifdef  USER_INIT
#undef  USER_INIT
#endif

#define USER_INIT local_init()
#ifdef  USER_END
#undef  USER_END
#endif

#define USER_END local_end()


struct buffer_state{
	FILE *input_file;
	char *ch_buf;				//输入缓冲区
	char *buf_pos;				//输入缓冲区的当前位置
	unsigned int buf_size;		//输入缓冲区的大小,不包括结束标志
	int n_chars;				//输入缓冲区中字符数目,不包括结束标志
	int is_our_buffer;			//是否拥有这个缓冲区,同智能指针的解决方案
	int is_interactive;			//是否是交互式的输入源,如果是控制台则input_file为空
	int at_bol;					//是否在行开始
	int fill_buffer;			//如果缓冲区数据用完,是否读入新的数据,如果为0的话表示文件结束
	int buffer_status;			//缓冲区状态,下面有定义

#define BUFFER_NEW			0
#define BUFFER_NORMAL		1
#define BUFFER_EOF_PENDING	2
};

typedef struct buffer_state *BUFFER_STATE;
#define END_OF_BUFFER_CHAR 0	//结束标志
#define BUF_SIZE		 1024	//定义缓冲区大小
#define READ_BUF_SIZE 1024

//当前缓冲区和它的窗口变量

static  BUFFER_STATE current_buffer = 0;
#define CURRENT_BUFFER current_buffer

static  char hold_char;
static  int  n_chars;

#define MORE_ADJ 0

static  char *text;
static  char *c_buf_p = (char *) 0;


void load_buffer_state( void ){
	n_chars = current_buffer->n_chars;
	text = c_buf_p = current_buffer->buf_pos;
	in = current_buffer->input_file;
	hold_char = *c_buf_p;
	}

//使b中的所有数据失效,如果b为当前缓冲区则重新装载窗口变量
void flush_buffer( BUFFER_STATE b ){
	if ( ! b )
		return;
	b->n_chars = 0;
	b->ch_buf[0] = END_OF_BUFFER_CHAR;
	b->ch_buf[1] = END_OF_BUFFER_CHAR;
	b->buf_pos = &b->ch_buf[0];
	b->at_bol = 1;
	b->buffer_status = BUFFER_NEW;
	if ( b == current_buffer )
		load_buffer_state();
}

//使b无效,把file放入b中
void init_buffer( BUFFER_STATE b, FILE *file ){
	flush_buffer( b );
	b->input_file = file;
	b->fill_buffer = 1;
	b->is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
}

//创建一个包装好的缓冲区(file,size)
BUFFER_STATE create_buffer( FILE *file, int size ){
	BUFFER_STATE b;
	b = (BUFFER_STATE) flex_alloc( sizeof( struct buffer_state ) );
	if ( ! b )
		fatal_error( "out of dynamic memory in create_buffer()" );
	b->buf_size = size;
	b->ch_buf = (char *) flex_alloc( b->buf_size + 2 );
	if ( ! b->ch_buf )
		fatal_error( "out of dynamic memory in create_buffer()" );
	b->is_our_buffer = 1;
	init_buffer( b, file );
	return b;
}

// 释放缓冲区控制块和缓冲区
void delete_buffer( BUFFER_STATE b ){
	if ( ! b )
		return;
	if ( b == current_buffer )
		current_buffer = (BUFFER_STATE) 0;
	if ( b->is_our_buffer )
		flex_free( (void *) b->ch_buf );
	flex_free( (void *) b );
}

/*定义get_next_buffer的返回结果*/
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2

static int get_next_buffer();		//取下一个缓冲区
static int input();					//取下一个字符
static void unput( int c, register char *bp );
void restart( FILE *input_file );

#ifdef STRING
static int myinput(char* buf, int max);
#define INPUT(buf,result,max) {result = myinput(buf,max);}
#else 
#define INPUT(buf,result,max_size)\
	if ( current_buffer->is_interactive )\
		{ \
		int c = '*', n; \
		for ( n = 0; n < max_size && \
			     (c = getc( in )) != EOF && c != '\n'; ++n ) \
			buf[n] = (char) c; \
		if ( c == '\n' ) \
			buf[n++] = (char) c; \
		if ( c == EOF && ferror( in ) ) \
			fatal_error( "input in flex scanner failed" ); \
		result = n; \
		} \
	else if ( ((result = fread( buf, 1, max_size, in )) == 0) \
		  && ferror( in ) ) \
		fatal_error( "input in flex scanner failed" );
#endif


//内存分配
static void *flex_alloc( unsigned int size ){
	return (void *) malloc( size );
}

static void *flex_realloc( void *ptr, unsigned int size ){
	return (void *) realloc( (char *) ptr, size );
}
static void flex_free( void *ptr ){
	free( ptr );
}

/* 放回数据,与下面取数据函数相反*/
static void unput( int c, register char *bp ){
	register char *cp = c_buf_p;
	if(c==10)
		linenum--;
	*cp = hold_char;
	if ( cp < current_buffer->ch_buf + 2 ){
		register int number_to_move = n_chars + 2;
		register char *dest = &current_buffer->ch_buf[
					current_buffer->buf_size + 2];
		register char *source =
				&current_buffer->ch_buf[number_to_move];
		while ( source > current_buffer->ch_buf )
			*--dest = *--source;
		cp += (int) (dest - source);
		bp += (int) (dest - source);
		current_buffer->n_chars =
			n_chars = current_buffer->buf_size;
		if ( cp < current_buffer->ch_buf + 2 )
			fatal_error( "flex scanner push-back overflow" );
		}
	text = bp;
	hold_char = c;
	c_buf_p = --cp;
	*cp=0;
}

static int input(){
	int c;
	*c_buf_p = hold_char;
	if ( *c_buf_p == END_OF_BUFFER_CHAR ){
		if ( c_buf_p < &current_buffer->ch_buf[n_chars] )
			*c_buf_p = '\0';//数据本身为0,而不是缓冲区结束
		else{
			int offset = c_buf_p - text;
			++c_buf_p;
			switch ( get_next_buffer() ){//读下一个缓冲区
				case EOB_ACT_LAST_MATCH:
					restart( in );
				case EOB_ACT_END_OF_FILE:
					return EOF;
				case EOB_ACT_CONTINUE_SCAN:
					c_buf_p = text + offset;
					break;
				}
			}
		}
	c = *(unsigned char *) c_buf_p;
	hold_char = *++c_buf_p;
	*c_buf_p = '\0';	//形成字符串text
	if(c==10)
		linenum++;
	return c;
}

//读取下一个有效的缓冲区
static int get_next_buffer(){
	register char *dest = current_buffer->ch_buf;//源区
	register char *source = text;//目的区
	register int number_to_move, i;
	int ret_val;
	if ( c_buf_p > &current_buffer->ch_buf[n_chars + 1] )//如果越过了两个结束标志
		fatal_error("fatal flex scanner internal error--end of buffer missed" );
	if ( current_buffer->fill_buffer == 0 ){ //文件结束
		if ( c_buf_p - text - MORE_ADJ == 1 ){
			return EOB_ACT_END_OF_FILE;
		}else{
			return EOB_ACT_LAST_MATCH;
		}
	}
	/* Try to read more data. */
	/*将text到c_buf_p处的字符拷贝到缓冲区头部*/
	number_to_move = (int) (c_buf_p - text) - 1;
	for ( i = 0; i < number_to_move; ++i )
		*(dest++) = *(source++);
	if ( current_buffer->buffer_status == BUFFER_EOF_PENDING )
		current_buffer->n_chars = n_chars = 0;
	else{
		int num_to_read =
			current_buffer->buf_size - number_to_move - 1;
		while ( num_to_read <= 0 ){ /* Not enough room in the buffer - grow it. */
			/* just a shorter name for the current buffer */
			BUFFER_STATE b = current_buffer;
			int c_buf_p_offset =
				(int) (c_buf_p - b->ch_buf);
			if ( b->is_our_buffer ){
				int new_size = b->buf_size * 2;
				if ( new_size <= 0 )
					b->buf_size += b->buf_size / 8;
				else
					b->buf_size *= 2;
				b->ch_buf = (char *)
					/* Include room in for 2 EOB chars. */
					flex_realloc( (void *) b->ch_buf,
							 b->buf_size + 2 );
			}else
				/* Can't grow it, we don't own it. */
				b->ch_buf = 0;
			if ( ! b->ch_buf )
				fatal_error("fatal error - scanner input buffer overflow" );
			c_buf_p = &b->ch_buf[c_buf_p_offset];

			num_to_read = current_buffer->buf_size -
						number_to_move - 1;
			}
		if ( num_to_read > READ_BUF_SIZE )
			num_to_read = READ_BUF_SIZE;
		/*读入更多的字符,n_chars为实践读入的字符数*/
		INPUT( (&current_buffer->ch_buf[number_to_move]),
			n_chars, num_to_read );
		current_buffer->n_chars = n_chars;
	}
	if ( n_chars == 0 ){
		if ( number_to_move == MORE_ADJ ){
			ret_val = EOB_ACT_END_OF_FILE;
			restart( in );
		}else{
			ret_val = EOB_ACT_LAST_MATCH;
			current_buffer->buffer_status =
				BUFFER_EOF_PENDING;
		}
	}else
		ret_val = EOB_ACT_CONTINUE_SCAN;
	n_chars += number_to_move;
	current_buffer->ch_buf[n_chars] = END_OF_BUFFER_CHAR;
	current_buffer->ch_buf[n_chars + 1] = END_OF_BUFFER_CHAR;
	text = &current_buffer->ch_buf[0];
	return ret_val;
}

//用文件input_file重新启动当前缓冲区
void restart( FILE *input_file ){
	if ( ! current_buffer )
		current_buffer = create_buffer( in, BUF_SIZE );
	init_buffer( current_buffer, input_file );
	load_buffer_state();
}

/* 如果在外部定义了STRING表示数据源为字符串
 * 字符串parseString由外部初始化,以作为数据源
 * parseString,parseCh用来从字符串中读入原始数据*/

#ifdef STRING
char *parseString=0;
static char *parseCh;

static int myinput(char* buf, int max){
	int len;
	if (parseCh == NULL)
		parseCh = parseString;
	len = strlen(parseCh);
	if (len > max)
		len = max;
	if (len > 0)
		memcpy(buf, parseCh, len);
	parseCh += len;
	return len;
}
#endif

/////////////////////////////////////////////
#ifdef _DEBUG
void print_result(FILE*o){
	fprintf(o,"%-8d%-8d%s\n",linenum,result_tuple.flag,text);
}
#endif

////////////////////////////////////////////////

int lex(){
    //init是一个静态变量初始值为1,表示要初始化
	if ( init ){
		init = 0;//表示已经执行初始化
//如果用户有自己的初始化函数,则调用它

#ifdef USER_INIT
		USER_INIT;
#endif
		if ( ! in )//如果输入文件为NULL,则使用标准输入
			in = stdin;
		if ( ! out )//如果输出文件为NULL,则使用标准输出
			out = stdout;
		if ( ! current_buffer )/*如果当前缓冲区为NULL,则创建*/
			current_buffer = create_buffer( in, BUF_SIZE );
		load_buffer_state();/*使当前缓冲区状态与窗口参数一至*/
	}
	int rc=LEX_NOTUPLE;
	register char c;
	while(rc==LEX_NOTUPLE){
		c=input();
		if(c==EOF){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -