语法分析器


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

void scaner();
void expression();
void term();
void factor();
void error();
void yuju();
int digit(char ch);
int letter(char ch);

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

int main()
{
	while (1)
	{
		Q = 0; ERROR = 0; syn = 0; sum = 0;
		p = 0;
		char ch1;
		printf("please input string:\n");
		do{
			ch = getchar();
			prog[p] = ch;
			p++;
		} while (ch != '#');
        ch1 = getchar(); //接收最后的回车符
		j = p;
		p = 0;
		while (p<j)
		{
			scaner();

			switch (syn)
			{
			case 20:  printf("(% 2d, %8.8g)\n", syn, sum);  break;
			case 10:  printf("(% 2d, %8s)\n", syn, token);  break;
			case -1:  printf("input error\n");   break;
			case -2:    break;
			default:  printf("(% 2d, % 8s)\n", syn, token);
				
				break;

			}
		}
		p = 0;
		yuju();
	}
}

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 == '	')
	{
		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 == '	')
	{
		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 == '	')
	{
		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;
			}
	}
	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];
					}
					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 yuju()
{
	scaner();
	expression();
	if (ERROR == 0&&syn==0)
		printf("\n------------\nsuccess\n------------\n");
	else
		printf("\n------------\nerror\n------------\n");
}
void expression()
{
	term();
	if (syn == 22 || syn == 23)
	{
		scaner();
		expression();
	}
}
void term()
{
	factor();
	if (syn == 24 || syn == 25)
	{
		scaner();
		term();
	}

}

void factor()
{
	if (syn == 10 || syn == 20)
	{
		scaner();
	}
	else
	{
		if (syn != 26)
			error();
		else
		{
			scaner();
			expression();
			if (syn != 27)
				error();
			else scaner();
		}
	}

}
void error()
{
	ERROR = 1;
}


 
 
 
 
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值