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

📄 parser.c

📁 语法分析
💻 C
字号:
// a.cpp: 主项目文件。
//#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char token[20];              //存放单词符号
char  prog[1024];            //存放源程序
char * p;					//Prog 指针
char ch;					//读取当前字符
int syn,m,n;				// syn 特征值
int presyn;					//记住前一个特征值,用于判断‘+’,‘-’是否属于后面数值的符号
char * rwtab[9]={"main","int","float","double","char","if","else","do","while"};  //关键字
double sum,decimal,integer;//用于数值单词的分析
int exp,expMark;           //指数,指数符号
int flag;                  //判断正负数
int k;

//词法分析部分
void initialize();       //每次扫描单词之前的一些初始化
void scan();			//扫描,得到单词
void printWord();       //输出单词

//语法分析部分
void expression();		//表达式
void term();			//项
void factor();			//因子

void main(int argc,char * argv[]){
	FILE *fp;
	if(argc==2)
		fp=fopen(argv[1],"r");
	else
	{
		fp=fopen("yjj.txt","r");
		if(fp==NULL)
		{
			printf("\tUsage:%s yjjFileName\n\tThe Default yjjFileName:yjj.txt\n",argv[0]);
			getchar();
			return;
		}
	}
	if(fp==NULL)
	{
		printf("File open error:%s\n",argv[1]);
		getchar();
		return;
	}
	fread(prog,1024,1,fp);
	p=prog-1;
	printf("%s\n",prog);
	presyn = 0;
	k=0;
//	do
//	{
		scan();		
		printWord();
		expression();
		if(syn == 1000 && k == 0)
			printf("\nSuccess\n");
		else
			printf("\nError\n");
//	}
//	while(syn!=-1&&syn!=0&&*(p+1)!='\0');
	fclose(fp);	
}

//用于单词的输出
void printWord()
{
	int i;
	switch(syn)                 
	{
	case 20 :
			for(i = 0; i < exp; i ++)
			{
				if(expMark == -1)
					sum /= 10;
				else
					sum *= 10;
			}
			sum = sum * flag;
			printf("( 20 , %e )\n",sum);break;
	case -1 : printf("ERROR!\n");break;
	case 0  : printf("( 0, # )\n");break;
	case 1000:break;
	default : printf("( %d , %s )\n",syn,token);
	}	
}

//每次扫描前的一些初始化工作
void initialize()
{
	ZeroMemory(token,20);  //清空token数组中的内容
	p++;				   //将指针指向下一位要读取的字符
	ch=*p;                 //读取当前字符
	m=0;                   //token的指针
	sum=0;                 //数值初始化为0,包括整数部分interger和小数部分decimal
	integer=0;
	decimal=0;
	exp=0;                 //exp初始化为0
	expMark=0;             //指数部分的符号
	flag=1;                //数值默认为整数
	presyn = syn;          //记住前一单词的种类
}

//单词扫描
void scan()
{
	int i;
	initialize();
	while(ch==' '||ch=='\t'||ch=='\n')
	{
		p++;
		ch=*p;
	}
	if(isalpha(ch))             //第一部分:关键字和标识符的识别              
	{
		while(isalnum(ch))
		{
			token[m++]=ch;
			p++;
			ch=*p;
		}			
		p--;
		token[m]='\0';
		for(n=0;n<6;n++)             //判断是否为关键字
		{
			if(strcmp(token,rwtab[n])==0)
			{
				syn=n+1;
				return;
			}
		}		
		syn=10;                 //是标识符    		
		return;
	}                           //第二部分:数值的识别,还要根据presyn进行符号识别
	if( isdigit(ch)||ch =='+'||ch =='-' )
	{	
		if(ch=='+')
		{			
			p++;
			ch=*p;
			if(presyn == 20||!isdigit(ch))
			{
				syn=22;
				token[0]='+';
				token[1]='\0';
				p--;
				return;
			}
		}
		if(ch=='-')
		{
			p++;
			ch=*p;
			if(presyn == 20||!isdigit(ch))
			{
				syn=23;
				token[0]='-';
				token[1]='\0';
				p--;
				return;
			}
			flag=-1;
		}
		while(isdigit(ch))
		{
			integer = (ch - '0') + 10 * integer;
			p++;
			ch = *p;
		}
		sum = integer;
		if(ch == '.')
		{
			p++;
			ch = *p;			
			if(isdigit(ch))
			{
				int n = 0;
				while(isdigit(ch))
				{
					n++;
					decimal = decimal * 10 + ch - '0';
					p++;
					ch = *p;
				}
				for(i = 0; i < n; i ++)
					decimal /= 10;
				sum += decimal;
				if(ch == 'e'||ch == 'E')
				{
					p++;
					ch = *p;			
					if(ch == '+' || ch == '-')
					{
						if(ch == '+')
							expMark = 1;
						else
							expMark = -1;
						p++;
						ch = *p;
						if(isdigit(ch))
						{
							while(isdigit(ch))
							{
								exp = exp * 10 + ch - '0';
								p++;
								ch = *p;
							}
							p--;							
							syn = 20;
						}
						else
						{
							p--;
							syn = -1;
						}
					}
					else if(isdigit(ch))
					{
						while(isdigit(ch))
						{
							exp = exp * 10 + ch - '0';
							p++;
							ch = *p;
						}
						p--;						
						syn = 20;
					}
					else
					{
						p--;						
						syn = -1;
					}
				}
				else
				{
					p--;				    
				    syn = 20;
				}			
			}
			else
			{
				p--;
				syn = -1;
			}
		}
		else if(ch == 'e'||ch =='E')
		{
			p++;
			ch = *p;			
			if(ch == '+' || ch == '-')
			{
				if(ch == '+')
					expMark = 1;
				else
					expMark = -1;
				p++;
				ch = *p;
				if(isdigit(ch))
				{
					while(isdigit(ch))
					{
						exp = exp * 10 + ch - '0';
						p++;
						ch = *p;
					}
					p--;					
					syn = 20;
				}
				else
				{
					p--;
					syn = -1;
				}
			}
			else if(isdigit(ch))
			{
				while(isdigit(ch))
				{
					exp = exp * 10 + ch - '0';
					p++;
					ch = *p;
				}
				p--;			
				syn = 20;
			}
			else
			{
				p--;				
				syn = -1;
			}
		}
		else
		{
			p--;
		    syn = 20;
		}
		return;
	}
	switch (ch)            //第三部分:其它单词的识别
	{
	case	'<':
		token[m++]=ch;
		p++;
		ch=*p;		
		if(ch=='=')		// <=
		{
			syn=35;
			token[m++]=ch;
			return;
		}
		syn=34;
		token[m]='\0';
		p--;
		return;
	case	'>':
		token[m++]=ch;
		p++;
		ch=*p;
		if(ch=='=')		//>=
		{
			syn=33;
			token[m++]=ch;
			return;
		}		
		syn=32;
		token[m]='\0';
		p--;
		return;		
	case	'*':
		syn=24;		
		token[0]=ch;
		token[1]='\0';
		//p++;
		return;
	case	'/':
		syn=25;		
		token[0]=ch;
		token[1]='\0';
		//p++;
		return;
	case	'=':		
		token[m++]=ch;
		p++;
		ch=*p;
		if(ch=='=')
		{
			syn=36;
			token[m++]=ch;
			return;
		}
		syn=21;
		token[m]='\0';
		p--;
		return;
	case	'!' :
		token[m++]=ch;
		p++;
		ch=*p;
		if(ch!='=')
		{
			syn=-1;
			p--;
			return;
		}
		syn=37;
		token[m++]='=';
		token[m]='\0';
		return;
	case	'(':
		syn=26;		
		token[0]=ch;
		token[1]='\0';
		//p++;
		return;
	case	')':
		syn=27;		
		token[0]=ch;
		token[1]='\0';
		//p++;
		return;
	case	'{' :
		syn=28;
		token[0]='{';
		token[1]='\0';
		return;
	case	'}' :
		syn=29;
		token[0]='}';
		token[1]='\0';
		return;	
	case	',' :
		syn=30;
		token[0]=',';
		token[1]='\0';
		return;
	case	';' :
		syn=31;
		token[0]=';';
		token[1]='\0';
		return;
	case	'\0' :
		syn=1000;
		token[0]=ch;
		token[1]='\0';
		return;
	case	'#' :
		syn=0;
		token[0]='#';
		token[1]='\0';
		return;
	default:
		syn=-1;
		//p++;
		return;
	}
	
}

void expression()
{
	term();
	while(syn == 22 || syn == 23)
	{
		scan();
		printWord();
		term();
	}
}

void term()
{
	factor();
	while(syn == 24 || syn == 25)
	{
		scan();
		printWord();
		factor();
	}
}

void factor()
{
	if(syn == 10 || syn == 20)
	{
		scan();
		printWord();
	}
	else if(syn == 26)
	{
		scan();
		printWord();
		expression();
		if(syn == 27)
		{
			scan();
			printWord();
		}
		else
		{
			printf("     ')'错误\n");
			k = 1;
		}
	}
	else
	{
		printf("         '('错误\n");
		k = 1;
	}
}

⌨️ 快捷键说明

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