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

📄 automata.cpp

📁 识别器
💻 CPP
字号:
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
#include <stdio.h>
using namespace std;

/*创建状态转换矩阵*/
int aut[10][7]={ 2, 0, 0, 0, 8, 9, 15,
                 2, 3, 5,11, 0, 0, 11,
                 4, 0, 0, 0, 0, 0, 0,
                 4, 0, 5,11, 0, 0, 11,
                 7, 0, 0, 6, 0, 0, 0,
                 7, 0, 0, 0, 0, 0, 0,
                 7, 0, 0,11, 0, 0, 11,
                 8, 0, 0, 0, 8, 0, 12,
                 0, 0, 0, 0, 0, 10, 14,
                 0, 0, 0, 0, 0, 0, 13};


/*创建关键字表*/
char keywords[30][12]={"program","begin","end","var","while","do",
                     "repeat","until","for","to","if","then","else",
                    	";", ":", "(", ")", ",", ":=", "+", "-", "*", "/",
                     ">", ">=", "==", "<", "<="};
char bounds[] = {';', ':', '(', ')', ',', '=', '+', '-', '*', '/','>',  '<'};             

/*符号表*/
char ID[50][12];

/*常数表*/
float C[20];

struct token{      //Token结构
    int code;
    int value;
 };

struct token tok[100];      //Token数组
int s;              //当前状态
int n,p,m,e,t;     //尾数值,指数值,小数位数,指数符号,类型
float num;         //常数值
char w[50];      //源程序缓冲区
string  strTOKEN;
int i;            //源程序指针,当前字符为w[i]


int currentID = 0;
int currentConstID = 0;
int currentToken = 0;

//方法声明
int InsertConst(float num);//将常数插入常数数组中
int InsertID(string token) ;// token 加入符号表数组
int  Reserve(string stringToken);
int isBounds(char ch); /*判断一个字符是否是界符*/
void act(int s);//语义操作
int find(int s,char ch);// 查状态变换表


//主程序
int main(int argc,char * argv[])
{ 
	ifstream sourcefile;	
	
   s=1;
       
 	if(2 != argc){
   	cerr<<"Usage: "<<argv[0]<<"source-file\n";
   	return 1;	
   	}
sourcefile.open(argv[1]);//打开文件

	while(!sourcefile.eof()){//如果文件已经结束 
		/*读入一行到w[i],i=0;*/
			int readCounter = 0;
			i = 0;			
			sourcefile.read(w,50);
			readCounter = sourcefile.gcount();
		do {                               //处理一行,每次处理一个单词
		  /*滤空格,直到第一个非空的w[i];*/
		  if(isspace(w[i])){
		 			i++;
		  		continue;
		  }
		  		
			if (isalpha(w[i]))       /*判定单词类别*/
				/*标识符或关键字;*/
				tok[currentToken].code = 2;
			else if (isdigit(w[i]))
				tok[currentToken].code = 1;
			else if (isBounds(w[i]))
			tok[currentToken].code = 1;
				 /*界符;*/
			else { /*非法字符错误;*/
				cout<<"Invalid char!\n";	
     			i++;
				continue;
           }

			i--;
			s = 1;

			//处理一个单词开始
			while (0 != s)//拼单词并生成相应Token
			{
			   act(s);                        //执行qs

				if (s>=11 && s<=14)      //一个单词处理结束
				  break;

			   i++;                       //getchar()
			   s=find(s, w[i]);
			}

			if (s==0)
			  cout<<"syntax error:";

		}while (i<readCounter);//('\n' != w[i])
	}    
			
	sourcefile.close();
	
	cout<<"Token 序列:"<<currentToken<<endl;	
	for(int count = 0;count< currentToken;++count)
		cout<<tok[count].code <<" "<<tok[count].value<<endl;
		
	cout<<"符号表:"<<endl;	
	for(count = 0;count< currentID;++count)
		cout<<ID[count]<<endl;
		
		
		cout<<"常数表:"<<endl;
	for(count = 0;count< currentConstID;++count)
		cout<<C[count]<<endl;
 return 0;
}

int InsertConst(float num){
	C[currentConstID] = num;
	return currentConstID++;
	
}

int InsertID(string token)
{
	for(int i=0;i<currentID;++i){
		if(token == ID[i])
			return i;
	}	
	strcpy(ID[currentID],token.c_str());	
	return currentID++;
}
int  Reserve(string stringToken)
{
	int keynum = 0;
	
	for(;keynum <=31;keynum++)
		if(stringToken == keywords[keynum])
			return keynum +1;

	return 0;		
}

/*判断一个字符是否是界符*/
int isBounds(char ch)
{
	for(int i = 0;i<12;++i)
		if(ch == bounds[i])
			return 1;
	return 0;
	
}
//语义操作
void act(int s)
{
	int value;
	int code;
	switch(s){
	case 1:
        n = m = p = t =0;
        e = 1; 
        num = 0;
        strTOKEN = "";
        break;
    case 2:
        n = 10 * n + (w[i] -'0');
        break;
    case 3:
        t = 1;
        break;
    case 4:
        n = 10 * n + ( w[i] -30); 
        m++;
        break;
    case 5:
        t = 1;
        break;
    case 6:
        if (w[i] == '-')
            e = -1;
        break;
    case 7:
        p = 10 * p + (w[i]-'0');
        break;
    case 8:		
    case 9:		
    case 10:
		strTOKEN += w[i]; /*将w[i]中的符号拼接到strTOKEN的尾部;*/	
		break;		
    case 11:
		num = n *(float)(pow(double(10),e*double(p-m)));     //计算常数值
		tok[currentToken].code=31; 
		tok[currentToken].value=InsertConst(num);
		++currentToken;//生成常数Token		
		break;
	case 12:
		code = Reserve(strTOKEN);         //查关键字表

      if (code){ //生成关键字Token
   	     tok[currentToken].code= code;
    	  tok[currentToken].value = 0;
		  ++currentToken;
 	   }else{
 	 		tok[currentToken].code=32; 
 	 	 	tok[currentToken].value=InsertID(strTOKEN);
			++currentToken;
   		}//生成标识符Token
		break;
	case 13:
		cout<<"strTOKEN:"<<strTOKEN<<endl;
		code=Reserve(strTOKEN);  //查界符表
		cout<<"cold:"<<code<<endl;
		 
       if (code){
   	      tok[currentToken].code=code; 
   	      tok[currentToken].value=0;
	      ++currentToken;
   	   }  //生成界符Token
		else {
			strTOKEN = strTOKEN.substr(0,strTOKEN.length()-1);   //单界符
			//源程序缓冲区指针减1;
			--i;
			code=Reserve(strTOKEN); 
			cout<<"code:"<<code<<endl;//查界符表
			tok[currentToken].code=code; 
			tok[currentToken].value =0;   //生成界符Token
			++currentToken;
		}

		break;

	case 14:
		code =Reserve(strTOKEN);         //查界符表
		tok[currentToken].code =code;  
		tok[currentToken].value=0;       //生成界符Token
		++currentToken;
		break;
   case 15:
			break;
default:
			break;

	}
}

int find(int s,char ch)
{
	int newState =0;	
    
    if(isdigit(w[i]))
        newState = aut[s-1][0];
    else if('.' == w[i])
        newState = aut[s-1][1];
    else if(isalpha(w[i]))
        newState = aut[s-1][4] + aut[s-1][2];		
    else if('+' == w[i] || '-' == w[i])
        newState = aut[s-1][3];		
    else if(isBounds(w[i]))
        newState = aut[s-1][5];
    else{
        newState = aut[s-1][6];		
	}
	return newState;
}

⌨️ 快捷键说明

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