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

📄 wordcompile.h

📁 一个Pascal子集语言的编译器
💻 H
📖 第 1 页 / 共 5 页
字号:
(*)                                                     输出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 + -