编译原理课程设计——语义分析器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define max 20
void scaner();
int digit(char ch);
int letter(char ch);
char **variable;//定义用户自变量信息表
FILE *fpw;
FILE *fprt;

void P();//递归下降主控制程序
void Parse();
void lrparser();//语句块 B
void yucu();//语句串  SS
void statement();//语句 S
void Equal();//赋值语句
void if_else();//条件语句
void do_while();//循环语句
int Condition();//条件
char * expression();//表达式
char * term();//项
char * factor();//因子
void error();
int i_quad = 0, k = 0, i_err = 0, i_erter = 0;
typedef struct quaternion{
 char res[max];
 char argv1[max];
 char op[max];
 char argv2[max];
}quad;
quad * pQuad;
int index,nSuffix;//四元式编号,临时变量编号
int state;

void emit(char *op,char *ag1,char*ag2,char *result);
char *Newtemp(void);
int merge(int p1,int p2);
void bp(int p,int t);


char prog[1000], token[8];
char ch;
int syn = 0, p, Q = 0, ERROR = 0;
double sum = 0;

int main()
{

		Q = 0; ERROR = 0; syn = 0; sum = 0;
		int j;
		p = 0;
		//printf("please input string:\n");
		/*do{
			ch = getchar();
			prog[p] = ch;
			p++;
		} while (ch != '#');*/
		if((fprt=fopen("C:\\Users\\hujiaxuan\\Documents\\codeblocksProject\\yuyi\\read.txt","rt"))==NULL){
            printf("\open file error!");
			exit(1);
		}
		while(ch!=EOF&&ch!='#'){
            ch=fgetc(fprt);
            prog[p]=ch;
            p++;
            putchar(ch);
		}
		fclose(fprt);
		j = p;

		p = 0;
		while (p<j)
		{
			scaner();

			switch (syn)
			{
			case 20:  printf("(% 2d, %8.8g)\n", syn, sum); Q++; break;
			case 10:  printf("(% 2d, %8s)\n", syn, token); Q++; break;
			case -1:  printf("input error\n");   break;
			case -2:    break;
			default:  printf("(% 2d, % 8s)\n", syn, token);
				if (syn>0 && syn < 10) Q++;
				else Q = 0;
				break;

			}
		}
         p = 0;
		Parse();

}

void scaner()
{
	int n, i = 0;
	char *rwtab[9] = { "main", "int", "float", "double", "char", "if", "else", "do", "while" };
	for (n = 0; n<8; n++)
		token[n] = '\0';
	ch = prog[p];
	//去除多余空格 Tab 换行
	while (ch == ' ' || ch == '\n' || ch == '	')
	{
		if (ch == '\n') i_erter++;
		p++;
		ch = prog[p];
	}
	//去除注释//
	if (ch == '/'&&prog[p + 1] == '/')
	{
		while (ch != '\n')
		{
			p = p + 2;
			ch = prog[p];
		}
		p++;
		ch = prog[p];
	}
	//去除多余空格 Tab 换行
	while (ch == ' ' || ch == '\n' || ch == '	')
	{
		if (ch == '\n') i_erter++;
		p++;
		ch = prog[p];
	}
	//去除注释/*
	if (ch == '/'&&prog[p + 1] == '*')
	{
		while ((ch == '*'&&prog[p + 1] == '/') != 1)
		{
			p++;
			ch = prog[p];
		}
		p = p + 2;
		ch = prog[p];
	}
	//去除多余空格 Tab 换行
	while (ch == ' ' || ch == '\n' || ch == '	')
	{
		if (ch == '\n') i_erter++;
		p++;
		ch = prog[p];
	}
	if (letter(ch))
	{
		while (letter(ch) || digit(ch))
		{
			token[i] = ch;
			i++;
			p++;
			ch = prog[p];
		}
		syn = 10;
		Q = 1;
		for (n = 0; n<9; n++)
			if (strcmp(token, rwtab[n]) == 0)
			{
				syn = n + 1;
				break;
			}
			if (strcmp(token, "then") == 0)
			{
				syn = 40;
			}
		}
		else if (digit(ch) || ch == '+' || ch == '-')
		{

			if (ch == '+' || ch == '-')
				if (digit(prog[p + 1]) && Q == 0){
					token[0] = ch;
					i++;
					p++;
					ch = prog[p];
				}
				else{
					if (ch == '+') { syn = 22; token[0] = ch; p++; Q = 0; }
					if (ch == '-') { syn = 23; token[0] = ch; p++; Q = 0; }
				}
				if (digit(ch))
				{
					syn = 20;
					Q = 1;
					while (digit(ch))
					{
						token[i] = ch;
						i++;
						p++;
						ch = prog[p];
					}
					sum = atoi(token);
					if (ch == '.'&&syn == 20)
					{
						token[i] = ch;
						p++;
						ch = prog[p];
						if (digit(ch))
						{
							while (digit(ch))
							{
								i++;
								token[i] = ch;
								p++;
								ch = prog[p];
							}
							i++;
							sum = atof(token);
						}
						else syn = -1;
					}
					if (ch == 'e'&&syn == 20)
					{
						token[i] = ch; i++;
						p++; ch = prog[p];
						token[i] = ch; i++;
						p++; ch = prog[p];
						if ((prog[p - 1] == '-' || prog[p - 1] == '+') && digit(ch))
						{
							while (digit(ch))
							{
								token[i] = ch;
								i++;
								p++;
								ch = prog[p];
							}
							sum = atof(token);
						}
						else syn = -1;
					}
				}
			}
			else{
				Q = 0;
				switch (ch)
				{
					case '*':syn = 24; token[0] = ch; p++; break;
					case '/':syn = 25; token[0] = ch; p++; break;
					case '(':syn = 26; token[0] = ch; p++; break;
						case ')':syn = 27; token[0] = ch; p++; break;
case '{':syn = 28; token[0] = ch; p++; break;
case '}':syn = 29; token[0] = ch; p++; break;
case ':':syn = 30; token[0] = ch; p++; break;
case ';':syn = 31; token[0] = ch; p++; break;
case '>':
p++;
ch = prog[p];
if (ch == '=')
{
	syn = 33;
	token[0] = '>'; token[1] = '=';
	p++;
}
else syn = 32; token[0] = '>';
break;
case '<':
p++;
ch = prog[p];
if (ch == '=')
{
	syn = 35;
	token[0] = '<'; token[1] = '=';
	p++;
}
else syn = 34; token[0] = '<';
break;
case '=':
p++;
ch = prog[p];
if (ch == '=')
{
	syn = 36;
	token[0] = '='; token[1] = '=';
	p++;
}
else syn = 21; token[0] = '=';
break;
case '!':
p++;
ch = prog[p];
if (ch == '=')
{
	syn = 37;
	token[0] = '!'; token[1] = '=';
	p++;
}
break;
case '#':syn = 0; token[0] = '#'; p++; break;
default: syn = -1; p++;
break;
}
}
}

int letter(char ch)
{
	if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'))
		return 1;
	return 0;
}

int digit(char ch)
{
	if (ch >= '0'&&ch <= '9')
		return 1;
	return 0;
}

void P()
{
    int nchain;
    scaner();
    if(syn==1){
        scaner();
        if(syn==26){
            scaner();
            if(syn==27){
                scaner();
                lrparser();
            }else error();
        }else error();
    }else error();
}

void lrparser(){//语句块
    if(syn==28){
        scaner();
        yucu();
        if(syn==29) scaner();
        else error();
    }else error();
}

void yucu(){//语句串
    statement();
    if (syn==31) scaner();
    while(syn!=29){
        statement();
     if(syn==31) scaner();
     else error();
    }
}

void statement(){//语句
    if(syn==10) Equal();
    else if(syn==6) if_else();
    else if(syn==8) do_while();

    else error();
}
void Equal(){ //赋值语句
    char temp[max];
    char *place;
    if(syn==10){
        strcpy(temp,token);
        scaner();
        if(syn==21){
            scaner();
            place=expression();
            emit("=",place,"",temp);

        }else  error();
    }else error();
}
void if_else(){
    int m,n;
    if(syn==6){
        scaner();
        m=Condition();
        lrparser();
        if(syn==7){
            scaner();
            n=index;
            emit("goto","","","0");
            itoa(index,pQuad[m].res,10);
            lrparser();
           itoa(index,pQuad[n].res,10);
        }else{
        itoa(index,pQuad[m].res,10);
        }
    }
}
int  Condition(){ //if_else 语句中的条件判断
    char ntc[max];
     char op[max],optmp[max],*place1,*place2;
    int m;
    place1=expression();
    if(syn>31&&syn<38){
     sprintf(op,"%s",token);
         scaner();
        place2=expression();
        sprintf(optmp,"goto %s",op);
        itoa(index+2,ntc,10);
        m=index+1;
        emit(optmp,place1,place2,ntc);
        emit("goto","","","0");//"0"标记需要回填
    }else error();
    return m;//返回需要回填的四元式序列号
}
int  Condition2(){ //do_while语句中的条件判断
    char ntc[max];
     char op[max],optmp[max],*place1,*place2;
    int m;
    place1=expression();
    if(syn>31&&syn<38){
     sprintf(op,"%s",token);
         scaner();
        place2=expression();
        sprintf(optmp,"goto %s",op);
        itoa(index+2,ntc,10);
        m=index;
        emit(optmp,place1,place2,"0");<span style="font-family: Arial, Helvetica, sans-serif;">//"0"标记需要回填</span>
        emit("goto","","",ntc);
    }else error();
    return m;//<span style="font-family: Arial, Helvetica, sans-serif;">返回需要回填的四元式序列号</span>
}
void do_while(){
    int k,b;
    if(syn==8){
        scaner();
        k=index;
        lrparser();
    if(syn==9){
        scaner();
        b=Condition2();
        itoa(k,pQuad[b].res,10);
    }else error();
    }else error();
}


char * expression()
{
    char op[max],*place1,*place2;
    char *place=(char *)malloc(max);
    place=place1=term();
    while(syn==22||syn==23){
        sprintf(op,"%s",token);
        scaner();
        place2=term();
        place=Newtemp();
        emit(op,place1,place2,place);
        place1=place;
    }
    return place;
}


char * term()
{
	char op[max],*place1,*place2;
	char *place;
	place=place1=factor();
	while(syn==24||syn==25){
        sprintf(op,"%s",token);
        scaner();
        place2=factor();
        place=Newtemp();
        emit(op,place1,place2,place);
        place1=place;
	}
    return place;
}

char * factor()
{
    char * place = (char *)malloc(max);
	if(syn==10){
        sprintf(place,"%s",token);
        scaner();
	}else if(syn==20){
        sprintf(place,"%g",sum);
        scaner();
	}else if(syn==26){
        scaner();
        place=expression();
        if(syn==27){
            scaner();
        }else error();
	}else error();
    return place;
}
void emit(char *op,char * argv1,char * argv2,char * result){
    sprintf(pQuad[index].op,"%s",op);
    sprintf(pQuad[index].argv1,"%s",argv1);
    sprintf(pQuad[index].argv2,"%s",argv2);
    sprintf(pQuad[index].res,"%s",result);
    index++;
}
char *Newtemp(){
    char * tmpID=(char *)malloc(max);
    sprintf(tmpID,"T%d",++nSuffix);
    return tmpID;
}


void printQuad(){
    int n;
    printf("four yuan List:\n");
    for(n=1;n<index;n++){
        printf("\n(%2d: %7s,%5s,%5s,%5s)",n,pQuad[n].op,pQuad[n].argv1,pQuad[n].argv2,pQuad[n].res);
    }
    return;
}
void Parse(){
    int i,nVar;
    p=0;
    state=0;
    variable = (char *)malloc(strlen(prog)*sizeof(char*));
    for(i=0;i<strlen(prog);i++)variable[i]=(char *)malloc(max);
    nVar=0;
    pQuad=(quad * )malloc(strlen(prog)*sizeof(quad));
    index=1;
    nSuffix=0;
    P();
    if(syn==0){
        printf("Success!\n");
        printQuad();
    }else printf("fail!");
}
void error()
{
    if (syn==20) printf("Syntax error before %g",sum);
    else printf("Syntax error before %s",token);
    printf("\nSyntax error before %s",token);
    system("pause");
}

  • 0
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值