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

📄 syntaxanalysis.c

📁 编译原理的语法分析器
💻 C
字号:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include "GLOBAL.H"

#define STRMAX 3000
#define SYMMAX 300
FILE *fp;
char buffer[SIZE];        // 缓冲区
struct entry symtable[SYMMAX];
char lexemes[STRMAX];
int lastentry = 0;

char* forward;           // 向前指针
char* lexeme_beginning;  // 词素开始指针

char c;
int state = 0, start = 0;
int lexical_value = 0;     // install_id() 和 install_num()返回的指针
char* token_beginning = 0; // 词素中首符号的索引

int lineno = 1;
int tokenval = NONE;
char lexbuf[BSIZE];

char *parent;
char digit[BSIZE];
char alp[BSIZE];
int d=0;a=0;
int isk=0;

struct entry terminal[]=
{
	"if",IF,
		"then",THEN,
		"else",ELSE,
		"while",WHILE,
		"do",DO,
		"begin",BEGIN,
		"end",END,	
		"no",NONE
};

char list();
char list1();   
char stmt();
char expr(e);
char expr1();
char term(t);
char term1();
char factor();
void MatchBeginEnd();
void MatchIfThenElse();
char ignorspace(c);
char match(c1);


// 出错记录函数 
void error(char* m)
{
	printf("   LINE %d: %s\n", lineno, m);
}

/* 将标识符插入符号表中 */
int insert(char s[], int tok)
{
    int len,lastchar=-1;
    len = strlen(s);
    if(lastentry + 1 >= SYMMAX)       error("symtable full");
    if(lastchar + len + 1 >= STRMAX)  error("lexemes array full");
	
    lastentry++;
    symtable[lastentry].token = tok;
    symtable[lastentry].lexptr = &lexemes[lastchar+1];
	
    lastchar = lastchar+len+1;
    strcpy(symtable[lastentry].lexptr, s);
    return lastentry;
}

/* 将关键字填入符号表 */
void init()
{
    struct entry *p;
    for(p = terminal/*keywords*/; p->token != NONE; p++)
    {
        insert(p->lexptr, p->token);
    }
}

/* 填充缓冲区 */

void filetobuffer()
{
	fread(buffer,1,SIZE-1,fp);
	buffer[SIZE-1]='\0';
}


/* 打印缓冲区 */

void printbuffer()
{
    printf("-----------------------The buffer is:-----------------------\n%s\n",buffer);
    printf("------------------------------------------------------------\n");
}
/* 回退amount个位置 */
char retract(int amount)
{   if(*forward != '\x0')
{
	forward -= amount;
}
return *forward;
}
/* 返回超前扫描字符 */
char nextchar()
{
    if(forward == NULL)    /* 刚开始扫描 */
    {
        forward = buffer;
    }
    else forward++;
    
    if(*forward == '\x0')
    {
        if( forward == &(buffer[SIZE - 1]) )
        {
            fread(buffer,1,SIZE/2 - 1,fp);
            buffer[SIZE/2 - 1] = '\x0';
            forward = buffer;
            return *forward;
        }
        else return '\x0';   // 文件已经处理完了     
    }
	
    return *forward;
}

/* 打印符号表 */
void printsymtable()
{
    int index;
    printf("\nThe symtable is:\n");
    printf("lexptr\ttoken");

    for(index = 1;symtable[index].lexptr != NULL;index++ )
    {
        printf("\n%s\t%d",symtable[index].lexptr,symtable[index].token);
    }
}

/* 试图修复程序错误 */
void recover()
{
    c = nextchar();
    while(c != '\n')
    {
		c = nextchar();
		if(c == '\x0')
		{
			return;
		}
    }
    lineno++;
    lexeme_beginning = forward + 1;
    state = 0;
}



/* 查找符号表中是否已记录s标识符 */
int lookup(s)
char s[];
{
    int p;
    for(p = lastentry; p > 0; p--)
    {
        if(strcmp(symtable[p].lexptr, s) == 0)
            return p;
    }
    return 0;
}


/* 插入符号表,这里只是简单输出 */
int install_id()
{
    int b,p=0; int i,scmp;
	char* pointer=lexeme_beginning;
	b=0;
    for(; pointer != (forward + 1); pointer++,b++)
        {
          if(*pointer == '\x0')
          {
              if(pointer == &(buffer[SIZE - 1]))
                    pointer = buffer;

          }				
            lexbuf[b] = *pointer;
    		if(b >= BSIZE)  error("compiler error");
        //  printf("%c",*pointer);		
        }  	
        lexbuf[b] = EOS;

		for(i = 0; i <lastentry; i++)
		{
			scmp =strcmp(/*keywords[i]*/terminal[i].lexptr, alp);//original use 'lexbuf' instead of 'alp
			if(scmp!=0){
				isk=1;
		//		continue;
			}
			else if(scmp==0) {
				isk=2;
				break;
			}
		}
				
		if(isk==1)	 //not keyword
		{		
			 //some sentence add here ...if possible
             //c5=1;			             
		}
	    if(isk==2)   //keyword
		{
            //some sentence add here ...if possible
		}


		p = lookup(lexbuf);
	//	if(p == 0)  p = insert(lexbuf, ID);
		tokenval = p;
		
		lexeme_beginning = forward;
		return symtable[p].token;
}

/* 用来存放num表项的值,这里只是简单输出 */
void install_num()
{
    char* p = lexeme_beginning;
    if(forward < lexeme_beginning)
    {
    printf("forward run too further than lexeme_beginning(in install_num())!");
        getch();
        exit(1);
    }
/*	
    printf("< NUM... ,");
    for(; p <= forward; p++)
    {
		if(*p != '\x0')
        {
           printf("%c",*p);
        }
    }
    putchar('>');
    putchar('\n');
*/
}

/* 当前模式匹配失败,开始下一轮匹配 */
int fail()
{
    forward = lexeme_beginning;
    if(*forward == '\x0')
    {
       start = 100;
    }
    retract(1);
    switch(start)
    {
        case 0:  start=  9;  break;
        case 9:  start= 12;  break;
		case 12: start= 20;  break;
		case 20: start= 25;  break;
    	case 25: start= 28;  break;
        
        case 28:
			error("Unknow Symbol!");//compiler error 
			recover();
			start = 0;
			break;
        default:
		//	printf("The file has been lexed!\n");
            printf("Fail...\n");
			getch();
            exit(0);
			break;
         
    }
    return start;
}

/* 得到文件的下一个词素 */
char nexttoken()
{

	while(1) {
		switch (state) 
		{ 
			case 0:   c = nextchar();          //c is lookahead character 
			          if (isspace(c) || c=='\r' || c== '\n')
					  {
						  if(c=='\n') lineno++;
					         state = 0;
					         lexeme_beginning++;       //advance beginning of lexeme 
					  }
		              else if (c == '<') state = 1;
			          else if (c == '=') 
					  {
						//state = 5;
						printf("< RELOP,EQ>\n");
						lexical_value = EQ;
					//	return RELOP;
						return c;
						}
					  else if (c == '>') state = 6;
					  else state = fail();
				   	  break;
													
			case 1:  c = nextchar();
				     if (c=='=') 
					 {
						//	state=2;
							printf("< RELOP,LE>\n");
							lexical_value = LE;
				//			return RELOP;
							return c;
						}
				      else if(c=='>') 
					  {
						//	state=3;
							printf("< RELOP,NE>\n");
							lexical_value = NE;
						//	return RELOP;
							return c;
						}
				      else
					  {
						//	state=4;
							retract(1);
							printf("< RELOP,LT>\n");
							lexical_value = LT;
						//	return RELOP;
							return c;
						}
																	
			case 6:   c = nextchar();
					  if(c=='=')
					  {
						//	state=7;
							printf("< RELOP,GE>\n");
							lexical_value = GE;
						//	return GE;
							return c;
						}
						else 
						{
						//	state=8;
							retract(1);
							printf("< RELOP,GT>\n");
							lexical_value = GT;
					//		return RELOP;
							return c;
						}
						break;
					
			case 9:  c = nextchar(); //c=ignorspace(c);
				      a=0;     //  alphabet  state 9 to 11
				     alp[a]=c;            
					 a++;                       
					if (isalpha(c)) 
						state = 10;
					else {
						a--;
						state=fail();
					}
					break;
												
			case 10: c = nextchar();
				    alp[a]=c;             
					a++;
					                             
					if (isalpha(c) || isdigit(c)) 
						state = 10; 						
					else state = 11;
					break;

			case 11:
					c=retract(1);
					 alp[a-1]='\0';
					                             
			//		lexical_value = install_id();
			//		return ( gettoken(lexical_value) ); //read token name from st
					install_id();
					
					return c;
			//		return ID;

					
			case 12: c=nextchar();   d=0;
				digit[d]=c;d++;
				if(isdigit(c))
				{
					state=13;}
				else {
					d--;
					state=fail();
				}
					 break;

			case 13: c=nextchar();
				digit[d]=c;d++;
				if(isdigit(c))	    state = 13;
				else if(c == '.')	state = 14;
				else if(c == 'E')	state=16;
				else {
					d--;
					state=fail();
				}
				break;


			case 14: c=nextchar();
				digit[d]=c;d++;
				if(isdigit(c)) state=15;
				else {
					d--;
					state=fail();
				}
				break;

			case 15: c=nextchar();
				digit[d]=c;d++;
				if(isdigit(c)) state=15;
				else if (c=='E') state=16;
				else {
					d--;
					state=fail();
				}
				break;

			case 16: c=nextchar();
				digit[d]=c;d++;
				if(c=='+'||c=='-') state=17;
				else if (c=isdigit(c)) state=18;
				else {
					d--;
					state=fail();
				}
				break;

			case 17: c=nextchar();
				digit[d]=c;d++;
				if(isdigit(c)) state=18;
				else {
					d--;
					state=fail();
				}
				break;

			case 18: c=nextchar();
				digit[d]=c;d++;
				if(isdigit(c)) state=18;
				else 
				{
					//state=19;     //digit.digitE+-digit
					digit[d-1]='\0';
					c=retract(1);
                    install_num();
					return c;
             //       return NUM;
				}
				break;

			
			case 20:  c=nextchar();      d=0;
				digit[d]=c;d++;
				if(isdigit(c)) 	state=21;
				else {
					d--;
					state=fail();
				}
				break;

			case 21: c=nextchar();
				digit[d]=c;d++;
				if(isdigit(c))   state=21;
				else if (c=='.') state=22;
				else {
					d--;
					state=fail();
				}
				break;

			case 22: c=nextchar();
				digit[d]=c;d++;
				if(isdigit(c))  state=23;
				else {
					d--;
					state=fail();
				}
				break;

			case 23: c=nextchar();   
				digit[d]=c; d++;
				if (isdigit(c))	state=23;
		/***/	else if(c=='E')
				{
                    c=retract(1);
					while(isdigit(c)|c=='.'){c=retract(1);}
					state=12;
				}
				else
				{
					//state=24;           //digit.digit 
					digit[d-1]='\0';
					c=retract(1);
                    install_num();
					return c;
             //       return NUM;   
				}
				break;


			case 25: c=nextchar();    d=0;      
				digit[d]=c;d++;
				if(isdigit(c)) 	  
					state=26;      
				else {
					d--;
					state=fail();
				}
				break;

			case 26: c=nextchar();  
				digit[d]=c; d++; 
				if(isdigit(c)) 	 state=26;       
		/***/	else if(c=='.')
				{
                    c=retract(1);
					while(isdigit(c)){c=retract(1);}
					state=20;
				}	
		/***/	else if(c=='E')
				{
                    c=retract(1);
					while(isdigit(c)){c=retract(1);}
					state=12;
				}
				else
				{
					//state=27
					digit[d-1]='\0'; //digit
			                    	
					c=retract(1);  
		                  				                
                    install_num();
					return c;
                  //  return NUM;
				}
				break;
	
				
			default: c=nextchar();
				{
//				printf("<  ,%c> ",c);				
//				error("Unknow Symbol!");
				return c;
				
				}
				break;
		}		
	}
}

#include "ParsingTree.h" // Insert parsingtree.h file here...

int main()
{
	int completed = 0;

	printf("    Syntax Analysis    BY J04120017\n");
	printf("list -> list ; stmt | stmt\n");
    printf("stmt -> IF expr THEN stmt\n");
	printf("      | IF expr THEN stmt ELSE stmt\n");
	printf("      | WHILE expr DO stmt\n");
	printf("      | BEGIN list END\n");
    printf("      | ID := expr\n");
	printf("expr -> expr + term | term\n");
	printf("term -> term * factor | factor\n");
	printf("factor -> (expr) | ID | NUM\n");

	printf("\nPLS INPUT:\n");
/**/
    init();
	gets(buffer);

//  printbuffer();    //print the content of the original file
    
    forward = NULL;
    lexeme_beginning = buffer;
    
    while(!completed)
    {
//	state = 0;
	start = 0;
printf("\nConstruct the tree from the LIST...\n\n");
parent=list();

    //if(c==EOS)
	printf("\n\nfinished!\n");
	return;
    lexeme_beginning = forward;
    lexeme_beginning++;
    }
	
	fclose(fp);
	free(lexemes);
	free(symtable);
	free(buffer);
	free(lexbuf);
	free(parent);
	 
    printsymtable();
    getch();
}

⌨️ 快捷键说明

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