📄 wordcompile.h
字号:
(*) 输出op 3
(/) 输出op 4
(.) 输出" ."
(,) 输出" ,"
a b c d e ....y z 0-9 : = ; ' " ( ) [ ] { } + - * / > < . , 空格 回车
(=)
2000 2000_输出" =="
(<)
2000 4100
4100 -----------------------(除">""="外)2000_输出" <"------------------------------
(<=)(<>)
2000 4100
4100 2000_输出"<=" 2000_输出"<>"
(>)
2000 4101
4101 -----------------------(除"="外)2000_输出" >"------------------------------
(>=)
4101 2000_输出"<="
5000(正在输入变量) -----------------对照符号表(2000,9000)--------------
5500(需要判断此变量是否合法)
5080
5081
5082
5083
5001
5002
5003
8881(接收程序名) 5081
8882(接收过程名称) 5082
8883(接收函数名称) 5083
8880(接收变量) 5080
8801(接收整型)
8802(接收浮点型)
8803(接收布尔型)
8888(完成一个词)--------转至5000------------------------------ --------------2000_输出该关键字---------------------
9999 注释代码
编译结果:生成一个文件,将 原代码转换成为一个新的代码,以便下面的语法分析器分析。
*****************************************************************************************/
//wordCompile类的定义信息
class wordCompile
{
private:
int CurrentLine; //记录当前行号
char* Errors[20]; //记录了各种错误信息,并以下标为错误标号
int Error_Type[100]; //记录当前错误的标号
int Error_Count; //记录目前为止错误的数量
char TempWord[256]; //当前所读的词
int wordLength; //当前所读的词长度
int State; //状态机所处的状态
char NowChar; //当前读到的字符
int VariantCount; //记录变量的个数
char Variant[1000][256]; //记录每个变量的名称
int VariantType[1000]; //记录每个变量的类型(只能记录是程序名、函数名、过程名等)
ofstream fwordtable; //将字符列表写到列表文件中
ifstream fin;
ofstream fouttemp;
ifstream fintemp;
ofstream fout; //输入输出文件指针
int Phase; //判断此变量是函数的名称还是函数的参数
protected:
void Initialize(); //对词法分析器的初始化
void DefineErrors(); //错误信息的初始化
void CatchErrors(int num); //错误信息的输出
int Checking(int state, char chin); //根据状态和输入字符检查词法
char* ChangeWord(char* str); //将所记录下的字符串信息加以变形
void Finish(); //将temp.txt文件中的内容按照要求写到words.txt中
public:
int Compile(char* filename); //主模块
};
void wordCompile::Initialize()
/*
此模块中包含了初始化各个变量
*/
{
CurrentLine=1;
Error_Count=0;
wordLength=-1;
State=2000; //为分析器准备的状态机
VariantCount=1; //记录变量的数量
fwordtable.open("wordtable1.txt"); //准备好文件
DefineErrors(); //定义好错误信息
}
void wordCompile::DefineErrors()
/*
写入各种词法分析的错误信息
*/
{
Errors[0]="undefined symbol :Error C_100"; //变量未定义的错误
Errors[1]="'{' expected :Error C_101"; //注释中没有左括号
Errors[2]="variant expected :Error C_102"; //没有定义变量
Errors[3]="program name expected :Error C_103"; //没有定义程序名
Errors[4]="procedure name expected :Error C_104"; //没有定义过程名
Errors[5]="function name expected :Error C_105"; //没有定义函数名
Errors[6]="redeclared variant :Error C_106"; //重复定义变量,或是一个名称变量有双重意义
Errors[7]="illegal variant :Error C_107"; //数字后面加字符,无效的变量
Errors[8]="variant name too long :Error C_108"; //变量名称过长
Errors[9]="wrong relop type :Error C_109"; //关系符的错误
}
void wordCompile::CatchErrors(int num) //输出对应的错误信息
{
Error_Count++;
cout<<"Error("<<Error_Count<<"): at Line "<<CurrentLine<<": \""<<TempWord<<"\" "<<Errors[num]<<endl;
}
void wordCompile::Finish() //将分析出的词进行最后的处理,输出到words.txt中
/*
此模块主要处理的是几个标识符的小问题:
1。将 < =, > =, <> 分别转化为 <=, >=, <>
2。将 : = 转化为 assignop
*/
{
fintemp.open("temp.txt");
fouttemp.open("words.txt");
int temp1,temp2;
while(fintemp>>TempWord)
{
if(strcmp(TempWord,"relop")==0) //对'<','>'等的处理
{
fintemp>>temp1; //获取关系符的属性
fintemp>>TempWord;
if(strcmp(TempWord,"relop")==0) //连续获得两个关系符
{
fintemp>>temp2;
if((temp1==1)&&(temp2==0)) //">="
fouttemp<<"relop 4 ";
else if((temp1==2)&&(temp2==0)) //"<="
fouttemp<<"relop 3 ";
else if((temp1==2)&&(temp2==1)) //"<>"
fouttemp<<"relop 5 ";
else
{
fout<<"relop "<<temp2<<" ";
CatchErrors(9);
}
}
else //说明此关系符是单独出现的,则直接将其输出
fouttemp<<"relop "<<temp1<<" "<<TempWord<<" ";
}
else if(strcmp(TempWord,":")==0) //将 ":=" 转化为"assignop"
{
fintemp>>TempWord;
if(strcmp(TempWord,"relop")==0)
{
fintemp>>temp1;
if(temp1==0)
fouttemp<<" assignop ";
else
{
fouttemp<<": ";
CatchErrors(9);
}
}
else
fouttemp<<": "<<TempWord<<" ";
}
else
{
fouttemp<<TempWord<<" ";
if(strcmp(TempWord,"@")==0) fouttemp<<endl;
}
}
fouttemp<<endl<<endl;
}
char* wordCompile::ChangeWord(char* str) //将字符串作一定的转化
{
//消除左右两边的空格
while(TempWord[0]==' ') //左边的空格
{
for(int i=0;i<=wordLength;i++)
TempWord[i]=TempWord[i+1];
wordLength--;
}
while(TempWord[wordLength]==' ') //消除右边的空格
{
TempWord[wordLength--]='\0';
}
TempWord[wordLength+1]='\0'; //首先需要将字符串加个结尾
switch(TempWord[0])
{
case '+':return "op 1";
case '-':return "op 2";
case '*':return "op 3";
case '/':return "op 4";
case 'd':if (TempWord[1]=='i') return "op 5"; //"div"
return "do"; //"do"
break;
case 'm':return "op 6"; //"mod"
case '=':return "relop 0";
case ':':if(TempWord[1]=='=') return "="; //":="
else return ":";
case '>':
if(TempWord[1]=='=') return "relop 4";
else return "relop 1";
case '<':if(TempWord[1]=='=') return "relop 3";
else if(TempWord[1]=='>') return "relop 5";
else return "relop 2";
case '\n': //如果是回车符则需要添加一个标记,以便语法分析
TempWord[0]='@';
TempWord[1]='\n';
TempWord[2]='\0';
return TempWord;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
for(int i=wordLength+1;i>=0;i--) //将数字整体向后移动,在前面插入"number "
TempWord[i+7]=TempWord[i];
TempWord[0]='n';
TempWord[1]='u';
TempWord[2]='m';
TempWord[3]='b';
TempWord[4]='e';
TempWord[5]='r';
TempWord[6]=' ';
return TempWord;
case 'i':if(TempWord[1]=='n') return "def 1"; //"integer"
else if(TempWord[1]=='d')
{
if(TempWord[2]=='s') return TempWord;
else return "id";
}
else
return "if";
case 'r':if(TempWord[3]=='l') return "def 2"; //"real"
else if(TempWord[3]=='d')
return "read";
else
return "record";
case 'b':if(TempWord[1]=='o') return "def 3"; //"boolean"
else return "begin";
default :
return TempWord;
break;
}
}
int wordCompile::Checking(int state, char chin)
/*
此部分是本模块中最核心的部分,主要功能是写出状态转移表,并判断下一步所要做的工作
返回值的意义:
0: 正常结束,且没有任何结果
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -