zoukankan      html  css  js  c++  java
  • 编译原理词法分析

    /*
    编译原理实验一:词法分析练习
    作者:李全锋
    时间:2013-9-28 
    */
    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    
    #define TOKENMAX 100
    #define PROGMAX 1000 
    #define K_ESC   27
    void analytics();      //词法分析
    void scanner();        //输入扫描
    bool isLetter(char ch);//判断字符是否为字母 
    bool isDigit(char ch);//判断字符是否为数字
    bool concat(char token[],char ch);//将ch连接在token后面 
    int reserve(char token[]);//对token中字符串查关键字表,若是关键字返回其编码,否则返回标识符种别码10
    double ezhishu(int x,double e);//求以e为底的指数
    bool isZheng11();//11正规式判断,判断是否是(+|-)d+(.d+)(ed+)的科学计数
    //全局变量
    char prog[PROGMAX],token[TOKENMAX];
    char ch;
    int syn,ptrp,ptrt;//ptrp是缓冲区prog的指针//ptrt是token的指针
    double sum;
    char *rwtab[6]={"begin","if","then","while","do","end"};
    
    int main(){
    	int key=0;
    	do{
    		fflush(stdin);//清空输入流
    		analytics();
    		printf("
    按Esc退出,其他键继续...
    ");
    		
    		if(!kbhit()){
    			key=getch();
    		}
    	}while(key!=K_ESC);
    
    	return 0; 
    } 
    
    //输入字符串并进行词法分析,返回二元组 
    void analytics(){
    	ptrp=0;
    	printf("请输入字符串,以#结尾:
    ");
    	do{
    		ch=getchar();
    		prog[ptrp++]=ch;
    
    			
    	}while(ch!='#');
    	ptrp=0;
    	do{
    		scanner();
    		switch(syn){
    			case 1:printf("(%2d,%8s)
    ",syn,token);break;
    			case 2:printf("(%2d,%8s)
    ",syn,token);break;
    			case 3:printf("(%2d,%8s)
    ",syn,token);break;
    			case 4:printf("(%2d,%8s)
    ",syn,token);break;
    			case 5:printf("(%2d,%8s)
    ",syn,token);break;
    			case 6:printf("(%2d,%8s)
    ",syn,token);break;
    			case 10:printf("(%2d,%8s)
    ",syn,token);break;
    			case 11:printf("(%2d,%lg)
    ",syn,sum);break;
    			case 13:printf("(%2d,%8s)
    ",syn,token);break;
    			case 14:printf("(%2d,%8s)
    ",syn,token);break;
    			case 15:printf("(%2d,%8s)
    ",syn,token);break;
    			case 16:printf("(%2d,%8s)
    ",syn,token);break;
    			case 17:printf("(%2d,%8s)
    ",syn,token);break;
    			case 18:printf("(%2d,%8s)
    ",syn,token);break;
    			case 20:printf("(%2d,%8s)
    ",syn,token);break;
    			case 21:printf("(%2d,%8s)
    ",syn,token);break;
    			case 22:printf("(%2d,%8s)
    ",syn,token);break;
    			case 23:printf("(%2d,%8s)
    ",syn,token);break;
    			case 24:printf("(%2d,%8s)
    ",syn,token);break;
    			case 25:printf("(%2d,%8s)
    ",syn,token);break;
    			case 26:printf("(%2d,%8s)
    ",syn,token);break;
    			case 27:printf("(%2d,%8s)
    ",syn,token);break;
    			case 28:printf("(%2d,%8s)
    ",syn,token);break;
    			
    			case 0:break;//#
    			case -1:printf("输入有误!");break;
    			default:printf("(%2d,%8s)
    ",syn,token);
    
    		}
    	}while(syn!=0 && syn!=-1);	
    }
    
    void scanner(){
    	int n;
    	for(n=0;n<TOKENMAX;n++) token[n]=NULL;
    	ch=prog[ptrp++];
    	n=0;
    	while((ch==32 || ch==10) && n++<PROGMAX)ch=prog[ptrp++];
    	
    	if(isLetter(ch)){		
    		//文法10
    		int temp=ptrp;
    		while(isDigit(ch) || isLetter(ch)){
    			concat(token,ch);
    			ch=prog[ptrp++];
    		}
    		ptrp--;
    		for (n=0;n<6;n++){
          	   if(strcmp(token,rwtab[n])==0)
               {  
               	   switch(n){
               	   	case 0:syn=1;return;
    				case 1:syn=2;return;
    				case 2:syn=3;return;
    				case 3:syn=4;return;
    				case 4:syn=5;return;
    			    case 5:syn=6;return;
    				
    				}
    		   }
           }
    		if(temp<=ptrp){
    			syn=10;			
    			return;
    		}
    	  
       }
       else	{
    		if(isDigit(ch))
    			{  
    				int temp=ptrp;
    				if(isZheng11()){
    					syn=11;
    					return;
    				}
    				ptrp=temp;
    			}
    			switch(ch){
    				case '<':
    					ptrt=0;
    					token[ptrt++]=ch;
    					ch=prog[ptrp++];
    					if (ch=='>')
    					{  syn=21;
    					    token[ptrt++]=ch;
    					}
    					else if (ch=='=')
    					{  
    						syn=22;
    					    token[ptrt++]=ch;
    				    }
    					else
    					{ 
    						syn=20;
    						ptrp--;
    					}
    					break;
    				case '>':
    					ptrt=0;
    					token[ptrt++]=ch;
    					ch=prog[ptrp++];
    					if (ch=='=')
    					{  syn=24;
    					    token[ptrt++]=ch;
    					}
    					else
    					{ 
    						syn=23;
    						ptrp--;
    					}
    					break;
    				case '+':
    					ptrt=0;
    					token[ptrt++]=ch;
    					ch=prog[ptrp++];
    					if(isDigit(ch)){
    						if(isZheng11()){
    							syn=11;
    							return;
    						}
    					}
    					else{
    						syn=13; token[0]='+';ptrp--; return;
    					}
    				case '-':
    					ptrt=0;
    					token[ptrt++]=ch;
    					ch=prog[ptrp++];
    					if(isDigit(ch)){
    						if(isZheng11()){
    							syn=11;
    							sum-=2*sum;
    							return;
    						}
    					}
    					else{
    						syn=14; token[0]='-';ptrp--; return;
    					}
    				case '*':syn=15; token[0]=ch; return;
    				case '/':syn=16; token[0]=ch; return;
    				case ':':
    					ptrt=0;
    					token[ptrt++]=ch;
    					ch=prog[ptrp++];
    					if (ch=='=')
    					{  syn=18;
    					    token[ptrt++]=ch;
    					}
    					else
    					{ 
    						syn=17;
    						ptrp--;
    					}
    					return;
    				case '(':syn=27; token[0]=ch; return;
    				case ';':syn=26; token[0]=ch; return;
    				case '=':syn=25; token[0]=ch; return;
    				case ')':syn=28; token[0]=ch; return;
    				case '#':syn=0;  token[0]=ch; return;
    				default: 
    					
    				    syn= -1;  token[0]=ch;return ;
    
    			}
    		
    
       } 
    
    }
    bool isLetter(char ch){
    	return ((ch >64 && ch <91) || (ch >96 && ch <123));
    }
    bool isDigit(char ch){
    	return (ch >47 && ch <58);
    }
    bool concat(char token[],char ch){
    	int i=0;
    	while(i< TOKENMAX){
    		if(token[i] == NULL){
    			token[i]=ch;
    			return true;
    		}
    		i++;
    	}
    	return false;
    }
    
    bool isZheng11(){
    	int temp1=ptrp;
    	int temp2=ptrp;
    	sum=0;
    	while(isDigit(ch)){
    		sum=sum*10+ch-'0';
    		ch=prog[ptrp++];
    	}
    	temp1=--ptrp;
    	if(ch=='.'){
    		//xiaoshu
    		ch=prog[++temp1];
    		double dot=0.1;
    		while(isDigit(ch)){
    			sum=(ch-'0')*dot+sum;
    			ch=prog[++temp1];
    			dot*=0.1;
    		}
    		
    		if(ch=='e'){//kexue
    			ch=prog[++temp1];
    			temp2=temp1;
    			int tempsum=0;
    			if(isDigit(ch)){
    				while(isDigit(ch)){
    					tempsum=10*tempsum+ch-'0';
    					//sum=sum*ezhishu((ch-'0'),10);
    					ch=prog[++temp1];
    				}
    				if(temp2<temp1){
    					sum=sum*ezhishu(tempsum,10);
    					ptrp=temp1;
    					return true;
    				}
    				ch='e';
    			}
    			else if(ch=='+'){
    				ch=prog[++temp1];
    				temp2=temp1;
    				int tempsum=0;
    				while(isDigit(ch)){
    					tempsum=tempsum*10+ch-'0';
    					//sum=sum*ezhishu(ch-'0',10);
    					ch=prog[++temp1];
    				}
    				if(temp2<temp1){
    					sum=sum*ezhishu(tempsum,10);
    					ptrp=temp1;
    					return true;
    				}
    				ch='+';
    			}
    			else if(ch=='-'){
    				ch=prog[++temp1];
    				temp2=temp1;
    				int tempsum=0;
    				while(isDigit(ch)){
    					tempsum=tempsum*10+ch-'0';
    					//sum=sum*ezhishu(ch-'0',0.1);
    					ch=prog[++temp1];
    				}
    				if(temp2<temp1){
    					sum=sum*ezhishu(tempsum,0.1);
    					ptrp=temp1;
    					return true;
    				}
    				ch='-';
    		
    			}
    			else{
    			}
    			ptrp=temp2-1;
    		
    		}
    		else if(temp1>=ptrp){
    			ptrp=temp1;
    			return true;
    		}
    		else{
    			
    		}
    	}
    	else if(ch=='e'){
    		//kexue jishu
    		ch=prog[++temp1];
    		temp2=temp1;
    		int tempsum=0;
    		if(isDigit(ch)){
    			
    			while(isDigit(ch)){
    				tempsum=10*tempsum+ch-'0';
    				//sum=sum*ezhishu((ch-'0'),10);
    				ch=prog[++temp1];
    			}
    
    			if(temp2<temp1){
    				sum=sum*ezhishu(tempsum,10);
    				ptrp=temp1;
    				return true;
    			}
    			ch='e';
    		}
    		else if(ch=='+'){
    			ch=prog[++temp1];
    			temp2=temp1;
    			int tempsum=0;
    			while(isDigit(ch)){
    				tempsum=tempsum*10+ch-'0';
    				//sum=sum*ezhishu(ch-'0',10);
    				ch=prog[++temp1];
    			}
    			if(temp2<temp1){
    				sum=ezhishu(tempsum,10)*sum;
    				ptrp=temp1;
    				return true;
    			}
    			ch='+';
    		}
    		else if(ch=='-'){
    			ch=prog[++temp1];
    			temp2=temp1;
    			while(isDigit(ch)){
    			sum=sum*ezhishu(ch-'0',0.1);
    			ch=prog[++temp1];
    			}
    			if(temp2<temp1){
    				ptrp=temp1;
    				return true;
    			}
    			ch=temp1-2;
    			ch='-';
    		}
    		else{
    		}
    		ch='e';
    	}
    	else{
    		//zhengshu
    		
    	}
    	return true;
    }
    
    double ezhishu(int x,double e){
    	double sum=1;
    	for(;x-->0;sum*=e);
    	return sum;
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    


    编译原理课后练习,词法分析的题目。要求分析一个科学计数的正规式,实在不会化简,就直接写了

  • 相关阅读:
    npm, node, pm2 使用笔记
    没加证书的域名通过https访问,错误的访问到有证书的域名项目--已解决
    mysql数据库大表加索引
    上传大文件失败
    ifame 与父页面进行数据交互(跨域)
    windows平台编译PHP及扩展 和 踩过的坑
    vim 使用笔记
    git 在pull/push指定密钥文件
    记一次使用Xshell登陆提示所选用户密钥未在远程主机上注册
    学习网站与参考文档
  • 原文地址:https://www.cnblogs.com/james1207/p/3347911.html
Copyright © 2011-2022 走看看