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

📄 parse.c

📁 一个C语言编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
	#include <stdio.h>
	#include <ctype.h>
	#include <string.h>
	#include <malloc.h>
	//#define BUFFER_SIZE 512  预定义缓冲区大小
	#define KEY_MOUNT   32     // 预定义关键字个数
	#define ID_SIZE  200      //预定义关键字大小
	#define MAX_ID  2000
	//用来定义关键字的集合
	#define  ANTO 257
	#define  BREAK 258
	#define  CASE 259
	#define  CHAR 260
	#define  CONST 261
	#define  CONTINUE 262
	#define  DEFAULT 263
	#define  DO 264
	#define DOUBLE 265
	#define ELSE 266
	#define ENUM 267
	#define EXTERN 268
	#define FLOAT 269
	#define FOR 270
	#define GOTO 271
	#define IF 272
	#define INT 273
	#define LONG 274
	#define REGISTER 275
	#define RETURN 276
	#define SHORT 277
	#define SIGNED 278
	#define SIZEOF 279
	#define  STATIC 280
	#define  STRUCT 281
	#define  SWITCH 282
	#define TYPEDEF 283
	#define UNION 284
	#define UNSIGNED 285
	#define VOID 286
	#define VOLATILE 287
	#define WHILE 288
	//定义记号集合
	#define ID 289
	#define NUMBER 290
	#define STRING 291
	#define REAL 292
	#define RELOP 293
	#define LOGIC_OP 294
	#define PAIR_MATCH 295
	#define SINGLE_CHAR 296
	#define PREDEFINE 297
	#define PREINCLUDE 298
	#define DEPARTOR 299
	#define COMMA 300
	#define SELF_ADD 301
	#define SELF_SUB 302
	#define AND 303
	#define OR 304
	#define BIG_EQUAL 305
	#define SMA_EQUAL 306
	#define EQUIV 307
	#define REF 308
	#define REMAIN 309
	#define UNEQUAL 310
	#define DONE  311
	#define PARSE_ERROR  1000
//用一个链表存放符号表。
	struct symbol
	{
		char lexpre[ID_SIZE];
		int field;
		struct symbol *next;
	} ;   
	struct key
	{
		char *lexpre;
		int field;   
	}    
	symtable[KEY_MOUNT+1];    //用来存储关键字列表
//用来存储匹配符堆栈
	struct stack 
	{
		char pair_list[100];
		int top;	
	} pair;
	
	struct symbol *sym_list_head;
	struct symbol *sym_list_curr;
	
	int lineno=1; //行号
	char *lexeme; 
	FILE *res;  //源文件指针
	FILE *err;  //错误处理指针
	FILE *out_parse; //分析结果文件指针
	int token_type;  //记号类型
	int token_val;
	int flush=1;
	void init();           //初始化关键字列表
	int word_parse();
	void error(char *s);
	int insert(char *q,int token);
	int lookup(char *q);
	int is_full();
	void push(char c,struct stack *note);
	int pop(struct stack *note);
	int get_top(struct stack *note);
	int is_empty(struct stack *note);
	void test(struct stack *note);
	int main(int argc,char *argv[])
	{		
		int token;
		char name[64];
		init(); 
		printf("input the file to parse:");  
		scanf("%s",name);
		res=fopen(name,"r") ;
		freopen("error_test.txt","w+",stdout);
		printf("reopen in\n");
		if(res==NULL)
		{
			printf("error,can't open the file,please check the file path");
			exit(1);
		}  
		err=fopen("error.txt","w+");
		out_parse=fopen("word_parser_output.txt","w+ ");  
		token=word_parse();	
		while(token!=DONE)
			token=word_parse();
		putc(EOF,err);
		fclose(res);
		fclose(err);
        fprintf(out_parse,"line %d over\n",lineno);	
        fclose(out_parse);	 
		sym_list_curr=sym_list_head->next; 
		printf("TYPE               CONTEXT\n" );
		while(sym_list_curr!=NULL)
		{
			printf("%d:             %s\n",sym_list_curr->field,sym_list_curr->lexpre);
			sym_list_curr=sym_list_curr->next;
		}  
		test(&pair);
		getchar();
	}
	void init()
	{
		lexeme="auto\0break\0case\0char\0const\0continue\0default\0do\0double\0else\0enum\0extern\0float\0for\0goto\0if\0int\0long\0register\0return\0short\0signed\0sizeof\0static\0struct\0switch\0typedef\0union\0unsigned\0void\0volatile\0while\0"  ;

		symtable[1].field= ANTO;
		symtable[1].lexpre=lexeme;

		symtable[2].field= BREAK;
		symtable[2].lexpre=lexeme+5;

		symtable[3].field= CASE;
		symtable[3].lexpre=lexeme+11;

		symtable[4].field= CHAR;
		symtable[4].lexpre=lexeme+16;

		symtable[5].field= CONST;
		symtable[5].lexpre=lexeme+21;

		symtable[6].field= CONTINUE;
		symtable[6].lexpre=lexeme+27;

		symtable[7].field= DEFAULT;
		symtable[7].lexpre=lexeme+36;

		symtable[8].field= DO;
		symtable[8].lexpre=lexeme+44;

		symtable[9].field= DOUBLE;
		symtable[9].lexpre=lexeme+47;

		symtable[10].field= ELSE;
		symtable[10].lexpre=lexeme+54;

		symtable[11].field= ENUM;
		symtable[11].lexpre=lexeme+59;

		symtable[12].field= EXTERN;
		symtable[12].lexpre=lexeme+64;

		symtable[13].field= FLOAT;
		symtable[13].lexpre=lexeme+71;

		symtable[14].field= FOR;
		symtable[14].lexpre=lexeme+77;

		symtable[15].field= GOTO;
		symtable[15].lexpre=lexeme+81;

		symtable[16].field= IF;
		symtable[16].lexpre=lexeme+86;

		symtable[17].field= INT;
		symtable[17].lexpre=lexeme+89;

		symtable[18].field= LONG;
		symtable[18].lexpre=lexeme+93;

		symtable[19].field= REGISTER;
		symtable[19].lexpre=lexeme+98;

		symtable[20].field= RETURN;
		symtable[20].lexpre=lexeme+107;

		symtable[21].field= SHORT;
		symtable[21].lexpre=lexeme+114;

		symtable[22].field= SIGNED;
		symtable[22].lexpre=lexeme+120;

		symtable[23].field= SIZEOF;
		symtable[23].lexpre=lexeme+127;

		symtable[24].field= STATIC;
		symtable[24].lexpre=lexeme+134;

		symtable[25].field= STRUCT;
		symtable[25].lexpre=lexeme+141;

		symtable[26].field= SWITCH;
		symtable[26].lexpre=lexeme+148;

		symtable[27].field= TYPEDEF;
		symtable[27].lexpre=lexeme+155;

		symtable[28].field= UNION;
		symtable[28].lexpre=lexeme+163;

		symtable[29].field= UNSIGNED;
		symtable[29].lexpre=lexeme+169;

		symtable[30].field= VOID;
		symtable[30].lexpre=lexeme+178;

		symtable[31].field= VOLATILE;
		symtable[31].lexpre=lexeme+183;

		symtable[32].field= WHILE;
		symtable[32].lexpre=lexeme+192;
		token_val=0;
		sym_list_head=sym_list_curr=(struct symbol *)malloc(sizeof(struct symbol));
	}
	int word_parse()
	{

		int curr_ch;
		int next_ch;
		int last_ch;
		char records[ID_SIZE]={0};
		int i,j,k;      
        printf("line :%d word ----->\n",lineno);	  	
		while(1)
		{
		    
			curr_ch=getc(res);			
			if(lineno==57)
            printf("line :%d word ----->\n",lineno);
			if(curr_ch=='/')
			{            
				next_ch=getc(res);
				if(next_ch=='/')
				{
					while( curr_ch != EOF && curr_ch != '\n')
					{
						curr_ch=getc(res);
					}    

					if(curr_ch==EOF)
					{				
						return DONE;
					}			

					lineno++;
					continue;
				}

				else if(next_ch=='*')
				{					
					curr_ch=getc(res);
					next_ch=getc(res);				
							
					while( curr_ch != EOF && next_ch !=EOF)
					{
						if(curr_ch == '*' && next_ch == '/')
							break;
						else
						{
							if(curr_ch == '\n'  )
								lineno++;						
							curr_ch=next_ch;					   
							next_ch=getc(res);
						
						}
					}		     
					if(curr_ch == '*' && next_ch == '/')
					{						
						continue;
					}    
					if( curr_ch == EOF || next_ch ==EOF)
					{   					            
						return DONE;
					}    
				}          


				else
				{
					ungetc(next_ch,res); 
					fprintf(out_parse,"line %d:</RELOP>/<RELOP>\n",lineno);
					token_type='/';
					return token_type;
				}           
			}

			else if(curr_ch==' '|| curr_ch== '\t')           
				continue;    

			else if(curr_ch=='\n')
			{
              lineno++;
              continue;
          }    
			
			else if(curr_ch=='#')
			{				
				
				for(i=0;i<=6;i++)   
					records[i]= getc(res); 			
				
				*(records+7)='\0';
				if(!strcmp(records,"include"))
				{
					fprintf(out_parse,"line %d:</PREINCLUDE>#include<PREINCLUDE>\n",lineno);
					token_type=PREINCLUDE;
					return PREINCLUDE;
				}
				curr_ch=*(records+6);
				*(records+6)='\0';
				if(!strcmp(records,"define"))
				{
					fprintf(out_parse,"line %d:</PREDEFINE>#define<PREDEFINE>\n",lineno);
					token_type=PREDEFINE;
					return PREDEFINE;
				}
				ungetc(curr_ch,res);
				for(i=5;i>=0;i--)
					ungetc(*(records+i),res);
				error("illegar character in prefine");
				continue;
			}

			else if(isalpha(curr_ch)||curr_ch=='_')
			{
				i=j=0;
				k=0;
				while( isalnum(curr_ch) || curr_ch == '_')
				{
					*(records+(i++))=curr_ch;
					if(i > ID_SIZE)
					{
						error("identifier too long ,over the max size");
						break;
					}    
					curr_ch=getc(res);
				}
				*(records+i)='\0';
				ungetc(curr_ch,res);

				k=lookup(records);
				if(k>0)
				{
					fprintf(out_parse,"line %d:</KEYWORD>%s<KEYWORD>\n",lineno,records);
					return  k;
				}				

				insert(records,ID);				
				fprintf(out_parse,"line %d:</ID>%s<ID>\n",lineno,records);
				token_type=ID;
				return ID;

			}

			else if(curr_ch==EOF)
			{
				printf("line %d face EOF\n",lineno); 
				error("face EOF");
				return DONE;
			}

			else if(isdigit(curr_ch))
			{
				j=k=0;
				while(isdigit(curr_ch))
				{				
					*(records+(j++))=curr_ch;
					curr_ch=getc(res);
				}
				token_type=NUMBER;
				if(curr_ch=='.')
				{
					*(records+(j++))=curr_ch;
					curr_ch=getc(res);
					if(!isdigit(curr_ch))
					{
						printf("unexpected character in number %c\n",curr_ch);
						error("unexpected character in number");						
						*(records+(j++))='0';
					}
					else
					{
						while(isdigit(curr_ch))
						{
							*(records+(j++))=curr_ch;
							curr_ch=getc(res);
						}
						token_type=REAL;
					}
				}
				if(curr_ch=='e')
				{
					*(records+(j++))=curr_ch;
					curr_ch=getc(res);
					if(curr_ch=='+' || curr_ch== '-' )
					{
						*(records+(j++))=curr_ch;   
						curr_ch=getc(res);                    
					}    
					if(!isdigit(curr_ch))
						*(records+j)='0';
					while(isdigit(curr_ch))
					{
						*(records+(j++))=curr_ch;
						curr_ch=getc(res);
					}
					token_type=REAL;
					ungetc(curr_ch,res);
				}
				else				
					ungetc(curr_ch,res);

⌨️ 快捷键说明

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