📄 parser.cpp
字号:
#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 = ¤t_buffer->ch_buf[
current_buffer->buf_size + 2];
register char *source =
¤t_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 < ¤t_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 > ¤t_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( (¤t_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 = ¤t_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 + -