语法分析——在之前基础上增加定义语句打印,定义语句判断,增加对if-else-then的条件语句的判断

这是对之前的代码的扩充。

#include <bits/stdc++.h>
using namespace std;

/*
变量说明:
 line	从终端读入的字符串;		当前所指位置在计数器 p
 token	为存放的单词自身字符串;当前所指位置在计数器 m
 number	整型常数
 sym	每个单词符号种类

*/

enum symbol
{
    period=0,
    ident=1,
    number=2,
    Plus=3,
    Minus=4,
    times=5,
    slash=6,
    eql=7,
    neq=8,
    lss=9,
    leq=10,
    gtr=11,
    geq=12,
    lparen=13,
    rparen=14,
    semicolon=15,
    becomes=16,
    beginsym=17,
    endsym=18,
    ifsym=19,
    thensym=20,
    whilesym=21,
    dosym=22,
    note=23,
    elsesym=24,
    intsym=25,
    doublesym=26,
    floatsym=27,
    longsym=28,
    comma=29,
    nil=30,
};

char line[100],token[10],ch;
enum symbol sym;
int p,m, num;
char *word[11]= {"begin","end", "if","then","while","do","else","int","double","float","long"};
int Err;
bool flag=true;

void getsym();
int block();
void error(int i);
void statement();
void expression();
void term();
void factor();
void condition();
void Relational_operator();
void is_ident();
vector<string> define;

int main()
{
	//freopen("tt.txt","r",stdin);
    //读了字符串, 直到遇.结束
    p=0;
    printf("\n please input a string(end with '.'): ");
    do
    {
        scanf("%c",&ch);
        line[p++]=ch;
    }
    while(ch!='.');
    line[p++]='\0';
	define.clear();
    //逐个单词扫描;
    Err = 0;
    p=0;
    getsym();				//当前扫描的单词存放在sym中
    block();
    if ((sym==0)&&(Err==0))
        printf("syntax parses success!\n");
    return 0;

}

void printSym(enum symbol sym)
{

	/************************************************
  ****										                    ****
	****         TODO: 输出单词                  ****
	****                                        ****
	*************************************************/
	switch(sym)
	{
	case period:
		return;
	case number:
		printf("(    number,%-10d)\n",num);
		break;
	case nil:
		printf("you have input a wrong string\n");
		break;
	case note:
		printf("this is notes\n");
		break;
	case Plus:
		printf("(      Plus,%-10s)\n","+");
		break;
	case Minus:
		printf("(     Minus,%-10s)\n","-");
		break;
	case times:
		printf("(     times,%-10s)\n","*");
		break;
	case slash:
		printf("(     slash,%-10s)\n","/");
		break;
	case eql:
		printf("(       eql,%-10s)\n","=");
		break;
	case neq:
		printf("(       neq,%-10s)\n","><");
		break;
	case lss:
		printf("(       lss,%-10s)\n","<");
		break;
	case leq:
		printf("(       leq,%-10s)\n","<=");
		break;
	case gtr:
		printf("(       gtr,%-10s)\n",">");
		break;
	case geq:
		printf("(       geq,%-10s)\n",">=");
		break;
	case lparen:
		printf("(    lparen,%-10s)\n","(");
		break;
	case rparen:
		printf("(    rparen,%-10s)\n",")");
		break;
	case semicolon:
		printf("( semicolon,%-10s)\n",";");
		break;
	case comma:
		printf("(     comma,%-10s)\n",",");
		break;
	case becomes:
		printf("(   becomes,%-10s)\n",":=");
		break;
	case beginsym:
		printf("(  beginsym,%-10s)\n","begin");
		break;
	case endsym:
		printf("(    endsym,%-10s)\n","end");
		break;
	case ifsym:
		printf("(     ifsym,%-10s)\n","if");
		break;
	case thensym:
		printf("(   thensym,%-10s)\n","then");
		break;
	case whilesym:
		printf("(  whilesym,%-10s)\n","while");
		break;
	case dosym:
		printf("(     dosym,%-10s)\n","do");
		break;
	case elsesym:
		printf("(   elsesym,%-10s)\n","else");
		break;
	case intsym:
		printf("(  intsym,%-10s)\n","int");
		break;
	case doublesym:
		printf("(    doublesym,%-10s)\n","double");
		break;
	case floatsym:
		printf("(     floatsym,%-10s)\n","float");
		break;
	case longsym:
		printf("(   longsym,%-10s)\n","long");
		break;
	case ident:
		printf("(     ident,%-10s)\n",token);
		break;
	default:
		break;
	}
}

void getsym()
{
	for(m=0; m<8;m++) token[m++]=NULL;
	ch=line[p++];
	m=0;
	/************************************************
  ****									                     	****
	****         TODO: 单词识别                 ****
	****                                        ****
	*************************************************/
	while((ch==' '||ch=='\n')) ch=line[p++];
	//字母打头的字符串;标识符
	if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
	{
		do
		{
			token[m++]=ch;
			ch=line[p++];
		}while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0'));
		sym=ident;
		token[m++]='\0';
		ch=line[p--];
		for(int n=0;n<11;n++)
		{
			if(strcmp(token,word[n])==0)
			{
				if(n==0) sym=beginsym;
				else if(n==1) sym=endsym;
				else if(n==2) sym=ifsym;
				else if(n==3) sym=thensym;
				else if(n==4) sym=whilesym;
				else if(n==5) sym=dosym;
				else if(n==6) sym=elsesym;
				else if(n==7) sym=intsym;
				else if(n==8) sym=doublesym;
				else if(n==9) sym=floatsym;
				else if(n==10) sym=longsym;
				break;
			}
		}

		/*TODO识别标识符IDENT和保留字*/

	}
	else if((ch<='9'&&ch>='0'))
	{
		num=0;
		do{
			num=num*10+ch-'0';
			ch=line[p++];
		}while((ch<='9'&&ch>='0'));
		ch=line[p--];
		sym=number;
		/*TODO识别数字NUMBER*/
	}
	else {
		switch(ch)
		{
		case ':':		//赋值符号
			token[m++]=ch;
			ch=line[p++];
			if(ch=='=')
			{
				sym=becomes;
				token[m++]=ch;
			}
			else{
				sym=nil;
			}
			break;
		case '<':		//<=和<符号
			token[m++]=ch;
			ch=line[p++];
			if(ch=='=')
			{
				token[m++]=ch;
				sym=leq;
			}
			else if(ch=='>'){
				token[m++]=ch;
				sym=neq;
			}
			else{
				sym=lss;
				p--;
			}
			break;
		case '>':		//>=和>符号
			token[m++]=ch;
			ch=line[p++];
			if(ch=='=')
			{
				sym=geq;
				token[m++]=ch;
			}
			else{
				sym=gtr;
				p--;
			}
			break;
		case '+':
			sym=Plus;
			token[m++]=ch;
			break;
		case '-':
			sym=Minus;
			token[m++]=ch;
			break;
		case '*':
			sym=times;
			token[m++]=ch;
			break;
		case '/':
			ch=line[p++];
			if(ch=='*'){
				//cout<<"in\n";
				char fr;//前面的一个符号
				fr='*';
				ch=line[p++];
				while(1){
					fr=ch;
					ch=line[p++];
					if(fr=='*'&&ch=='/') break;
				}
				sym=note;
				token[m++]=ch;
			}
			else
			{
				sym=slash;
				token[m++]=ch;
				p--;
			}
			break;
		case '=':
			sym=eql;
			token[m++]==ch;
			break;
		case '(':
			sym=lparen;
			token[m++]=ch;
			break;
		case ')':
			sym=rparen;
			token[m++]=ch;
			break;
		case ';':
			sym=semicolon;
			token[m++]=ch;
			break;
		case ',':
			sym=comma;
			token[m++]=ch;
			break;
		case '.':
			sym=period;
			token[m++]=ch;
			break;
		case ' ':
			token[m++]=ch;
			break;
		default:
			sym=nil;
			break;
		}
	}
	token[m++]='\0';
	//如果想看分析的每一个sym,请打开这个注释
    printSym(sym);


    //处理语句分析中的注释
    if(sym==note) getsym();
}

void error(int i)
{
    switch (i)
    {
    case 1:
        printf("Error %d: 没有检测到语句期望begin符号\n", i);
        break;
	case 2:
		printf("Error %d: 没有检测到赋值语句的 := 符号\n",i);
		break;
	case 3:
		printf("Error %d: 没有检测到条件语句的 then 符号\n",i);
		break;
	case 4:
		printf("Error %d: 没有检测到循环语句的 do 符号\n",i);
		break;
	case 5:
		printf("Error %d: 错误的句子!\n",i);
		break;
	case 6:
		printf("Error %d: 你写了数字!\n",i);
		break;
	case 7:
		printf("Error %d: 没有检测到 '(' 的 ')' 符号\n",i);
		break;
	case 8:
		printf("Error %d: 没有检测到因子\n",i);
		break;
	case 9:
		printf("Error %d: 没有检测到关系运算符\n",i);
		break;
	case 10:
		printf("Error %d: 没有检测到标识符\n",i);
		break;
    case 11:
        printf("Error %d: 没有检测到语句期望 end 符号\n", i);
        break;
	case 12:
		printf("Error %d: 没有检测到定义结束标记 ; 符号\n", i);
        break;
	case 13:
		printf("Error %d: %d 处的 %s 没有定义\n", i,p,token);
        break;
    default:
        break;
    }
    flag=false;
    Err++;
}

int block()
{
    cout<<"程序块分析\n";
    if (sym != beginsym)
    {
        error(1);
    }
    else
    {
        getsym();
        statement();		//语句处理
        while (sym == semicolon)
        {
            getsym();
            statement();		//语句处理
        }
        if (sym != endsym&&flag)
        {
            error(11);
        }
        getsym();
    }
	return 0;


}

void statement()
{
    /********************************************
     **** TODO: 语句处理(赋值/条件/循环) *****
     *******************************************/
	cout<<"语句处理\n";
    if(sym==ident)
    {
        //赋值语句
        cout<<"赋值语句分析\n";
        getsym();
        if(sym==becomes)
        {
            getsym();
            expression();
            //printf(" print( %s ) ",token);
        }
        else
        {
        	error(2);
            //printf("Error!赋值语句左部标识符后面应是赋值号 ':='\n");
            return;
        }
    }
    else if(sym==ifsym)
    {
        //条件语句
        cout<<"条件语句分析\n";
        getsym();
        condition();
        if(sym==thensym)
        {
        	getsym();
            statement();
            if(sym==elsesym){
				cout<<"else语句分析\n";
				getsym();
				statement();
            }
            else if(sym==endsym){
				return;
            }
            else{
				statement();
            }
        }
        else
        {
        	error(3);
            //printf("Error!条件语句条件后面应是 'then'\n");
            return;
        }
    }
    else if(sym==whilesym)
    {
        //循环语句
        cout<<"循环语句分析\n";
        getsym();
        condition();
        if(sym==dosym)
        {
        	getsym();
            statement();
        }
        else
        {
        	error(4);
            //printf("Error!循环语句条件后面应是 'do'\n");
            return;
        }
    }
    else if(sym==intsym||sym==doublesym||sym==floatsym||sym==longsym){
		//变量定义语句
		cout<<"变量定义语句分析\n";
		getsym();
		is_ident();
		getsym();
		while(sym==comma){
			getsym();
			is_ident();
		}
		if(sym!=semicolon){
			error(12);
			return;
		}

    }
    else
    {
    	error(5);
        //printf("错误的句子!\n");
        return;
    }
    if(sym==number)
    {
    	error(6);
        //printf("你写了数字!\n");
        return;
    }
}

void expression()
{
	cout<<"表达式处理\n";
    /********************************************
     *************** TODO: 表达式处理 *************
     *******************************************/
    if(sym==Plus||sym==Minus)
    {
        getsym();
        term();
    }
    else
    {
        term();
        while(sym==Plus||sym==Minus)
        {
            getsym();
            term();
        }
    }
}

void term()
{
	cout<<"项处理\n";
    /********************************************
     *************** TODO: 项处理 *************
     *******************************************/
    if(sym==times||sym==slash)
    {
        getsym();
        factor();
    }
    else
    {
        factor();
        while(sym==times||sym==slash)
        {
            getsym();
            factor();
        }
    }
}

void factor()
{
	cout<<"因子处理\n";
    /********************************************
     *************** TODO: 因子处理 *************
     *******************************************/
    if(sym==ident)
    {
    	string s(&token[0],&token[strlen(token)]);
		vector<string>::iterator result=find(define.begin(),define.end(),s);
		if ( result == define.end()){
			error(13);
		}
		else getsym();

	}
    else if(sym==number){
		getsym();
    }
    else if(sym==lparen)
    {
        getsym();
        expression();
        if(sym==rparen) getsym();
        else
        {
        	error(7);
            //printf("语法分析出错!请检查是否缺少 ')'\n");
            return;
        }
    }
    else
    {
    	error(8);
        //printf("Error!缺少因子\n");
        return;
    }
}

void condition()
{
	cout<<"条件处理\n";
    /********************************************
     *************** TODO: 条件处理 *************
     *******************************************/
    expression();
    //getsym();
    Relational_operator();
    getsym();
    expression();
}


void Relational_operator()
{
	cout<<"关系运算符处理\n";
    /********************************************
     *************** TODO: 关系运算符 *************
     *******************************************/
    if(sym==neq||sym==eql||sym==lss||sym==leq||sym==gtr||sym==geq||sym==8||sym==9||sym==10||sym==11||sym==12||sym==13)
	{
		//getsym();
	}
    else
    {
    	error(9);
        //printf("Error!缺少关系运算符\n");
        return;
    }
}

void is_ident()
{
	cout<<"标识符处理\n";
    /********************************************
     *************** TODO: 关系运算符 *************
     *******************************************/
    if(sym==ident)
	{
		//getsym();
		define.push_back(token);
	}
    else
    {
    	error(10);
        //printf("Error!缺少关系运算符\n");
        return;
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值