📄 automata.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 + -