分类:
2012-10-28 11:10:16
原文地址:Redy语法分析--扫描器的设计与实现 作者:NosicLin
代码下载: git clone git://git.code.sf.net/p/redy/code redy-code这一章的内容有:
扫描器的设计与实现
- #define SCANNER_DEFALUT_LITERIAL_SIZE 128
- struct scanner
- {
- struct lex_file* s_lf;
- int s_cur_token;
- int s_line;
- char* s_cur_literal;
- int s_literial_size;
- };
- static void sc_init(struct scanner* sc,struct lex_file* lf)
- {
- sc->s_lf=lf;
- sc->s_cur_token=TOKEN_UNKOWN;
- sc->s_line=1;
- sc->s_cur_literal=(char*)malloc(SCANNER_DEFALUT_LITERIAL_SIZE);
- sc->s_literial_size=SCANNER_DEFALUT_LITERIAL_SIZE;
- }
- struct scanner* sc_create(char* filename)
- {
- struct lex_file* lf=lf_create(filename);
- if(lf==NULL)
- {
- WARN("Open file[%s] Failed",filename);
- return NULL;
- }
- struct scanner* sc=(struct scanner*)malloc(sizeof(*sc));
- sc_init(sc,lf);
- return sc;
- }
- struct scanner* sc_stream_create(FILE* file)
- {
- struct lex_file* lf=lf_stream_create(file);
- if(lf==NULL)
- {
- WARN("Create Scanner Failed");
- return NULL;
- }
- struct scanner* sc=(struct scanner*)malloc(sizeof(*sc));
- sc_init(sc,lf);
- return sc;
- }
扫描器的销毁:
- void sc_destory(struct scanner* sc)
- {
- lf_destory(sc->s_lf);
- free(sc->s_cur_literal);
- free(sc);
- }
- static void sc_set_cur_literial(struct scanner* sc,char* buf,int length)
- {
- if(sc->s_literial_size<length+1)
- {
- char* new_space=(char*)malloc(length+1);
- free(sc->s_cur_literal);
- sc->s_cur_literal=new_space;
- }
- memcpy(sc->s_cur_literal,buf,length);
- sc->s_cur_literal[length]='\0';
- }
- int sc_next_token(struct scanner* sc)
- {
- struct lex_file* lf=sc->s_lf;
- char cur;
- char next=lf_next_char(lf);
- struct state* cur_state=&me_begin;
- struct state* next_state;
- struct state* finnal_state=NULL;
- while(1)
- {
- cur=next;
- if(cur==EOF)
- {
- sc->s_cur_token=TOKEN_EOF;
- break;
- }
- if(cur=='\n')
- {
- sc->s_line++;
- }
- next_state=state_next(cur_state,cur);
- if(next_state==&lex_state_err)
- {
- if(finnal_state==NULL)
- {
- sc->s_cur_token=TOKEN_ERR;
- }
- else
- {
- sc->s_cur_token=finnal_state->s_token;
- }
- break;
- }
- if(state_final(next_state))
- {
- finnal_state=next_state;
- lf_mark(lf);
- }
- next=lf_next_char(lf);
- cur_state=next_state;
- }
- sc_set_cur_literial(sc,lf->l_buf+lf->l_begin,lf->l_mark-lf->l_begin);
- lf_reset_to_mark(lf);
- return sc->s_cur_token;
- }
- int main(int argc,char** argv)
- {
- if(argc<2)
- {
- printf("usage %s [filename]\n",argv[0]);
- exit(0);
- }
- struct scanner* sc=sc_create(argv[1]);
- int token;
- int i=0;
- while(1)
- {
- i++;
- if(i%5==0)
- {
- printf("\n");
- }
- token=sc_next_token(sc);
- if(token==TOKEN_EOF)
- {
- break;
- }
- if(token==TOKEN_ERR)
- {
- goto err;
- }
- if(token==TOKEN_ID)
- {
- if(symbol_type(sc_token_string(sc))==TOKEN_ID)
- {
- printf("{variable,%s} ",sc_token_string(sc));
- }
- else
- {
- printf("{keyword,%s} ",sc_token_string(sc));
- }
- continue;
- }
- if(token==TOKEN_ANNO)
- {
- continue;
- }
- if(token==TOKEN_WS)
- {
- continue;
- }
- if(token==TOKEN_NEWLINE)
- {
- printf("{newline} ");
- continue;
- }
- printf("{%s,%s} ",token_name(token),sc_token_string(sc));
- };
- return 0;
- err:
- printf("err token at line %d\n",sc->s_line);
- return -1;
- }
- a=random()
- b=random()
- if a+b/2==557
- a.inc()
- if a/2
- a.dec()
- else
- a.inc()
- end
- elif a+b/3==6
- a.dec()
- else
- b=a/2
- end
- print a
- print b