精英盒子 -> 程序设计 -> 表示经过多天到研究,终于写好了预编译器 [打印本页]

outman 2012-08-11 18:13

表示经过多天到研究,终于写好了预编译器

RT
作用是把指定的汇编源码中的所有中文变量自动识别并替换成对应的英文变量,且为了提高效率,在运行结束后会把目前识别到的所有中文变量和自动生成的英文变量储存到文件里,方便下次调用。目前测试无问题。
ps1:昨天群里的有人说可以用正则表达式解决,或许这会是个好方法,但实在不想放弃写了这么久的东西
ps2:这个东西已经被我一怒之下重写了两次源码,现在发出的版本是贯彻”一个函数不应该超出一个屏幕“的中心思想解决的,这种方法的确很方便调试,但由于我图方便,用的全是全局变量,所以可读性绝对很差
  1. #include <iostream>
    #include <string>
    #include <fstream>
    #include <cctype>
    using namespace std;
    void addrecord();
    bool ischinese(char a);
    void ifisnew(int j);
    void autoreplace();
    void donew();
    void doold(int j);
    void addcn();
    void writeinrp();
    void writeinfile();
    void newreplace();

    //伟大的全局变量
    ifstream set("set.ini"),file;
    ofstream ofile;
    string a;
    bool isnew=0;
    int i=0,j=0;
    int filei=0,filej=0;
    int temp=0;//杂七杂八的int变量
    int strstart=0;
    int savej=0;
    int stringsize,tempj;
    string stringtemp("啊");
    int chsize=stringtemp.size();//用来了解一个汉字的字节长度
    char newname[20];
    bool inaddmode=0;//用来判断是否处于自动截取中文状态
    struct yoxi{
        string ch;
        string en;
    }*rp;
    string *rfile;
    yoxi *newrp;//用来暂存新的rp
    //伟大 的全局变量

    int main(int argc,char* argv[]){
        stringtemp="";
        while(!set.eof()){++i;getline(set,a);}//看文件有多少行
        --i;
        set.clear();
        set.seekg(ios::beg);
        rp=new yoxi[i];

        for(;j<i;++j){
            set>>rp[j].ch;//中文
            set>>rp[j].en;//英文    
        }
        set.close();

        file.open(argv[1]);
        filei=0;
        while(!file.eof()){++filei;getline(file,a);}//看文件有多少行
        --filei;
        file.clear();
        file.seekg(ios::beg);
        rfile=new string[filei];
        for(filej=0;filej<filei;++filej){
            getline(file,rfile[filej]);
            if((temp=rfile[filej].find(";"))!=string::npos){
                rfile[filej]=rfile[filej].substr(0,temp);
            }
        }
        file.close();
        
        for(filej=0;filej<filei;++filej){
        //首先替换set.ini中已有的记录
        autoreplace();
        savej=j;
        //然后开始寻找并添加新中文
        addcn();
        }
        string b="temp/"+(string)argv[1];
        ofile.open(b.c_str());
        for(filej=0;filej<filei;++filej){//改完后就该写入了
            ofile<<rfile[filej]<<endl;
        }
        ofile.close();
        delete [] rfile;
        delete [] rp;
        
    return 0;
    }

    void addrecord(){
        //cout<<"inad";cin.get();
        writeinrp();//内存中的数组所做的工作
        writeinfile();//写入文件
        inaddmode=0;
        newreplace();//再次替换
    }

    void newreplace(){
        stringtemp=rfile[filej];
        //cout<<rfile[filej]<<"\ntst";cin.get();
        rfile[filej]="";
        while((temp=stringtemp.find(rp[savej].ch.c_str()))!=string::npos){
            ifisnew(savej);
            if(isnew){
                /*
                cout<<stringtemp<<endl;
                while(ischinese(stringtemp[temp])){
                    if((++temp)==stringtemp.size()){break;}
                }
                rfile[filej]+=stringtemp.substr(0,temp);
                cout<<"new\n"<<rfile[filej]<<endl;
                stringtemp=stringtemp.substr(temp);
                cout<<stringtemp<<endl;
                continue;
                */
                donew();continue;
            }
            /*
            stringtemp.replace(temp,rp[savej].ch.size(),rp[savej].en);
            cout<<"old\n"<<stringtemp<<endl;
            rfile[filej]+=stringtemp.substr(0,temp+rp[savej].en.size());
            cout<<rfile[filej]<<endl;
            stringtemp=stringtemp.substr(temp+rp[savej].en.size());
            cout<<stringtemp<<endl;
            */
            doold(savej);
        }
        rfile[filej]+=stringtemp;
        //cout<<rfile[filej].size()<<endl<<stringsize;cin.get();
        tempj-=(stringsize-rfile[filej].size());
        stringsize=rfile[filej].size();
        ++savej;
        //cout<<"end\n";
    }

    bool ischinese(char a){
        return (!(a>=0&&a<=127));
    }

    void ifisnew(int j){
        isnew=0;
        if(temp==0&&temp+rp[j].ch.size()==stringtemp.size()){return;}
        if(temp==0){
            //cout<<"goopd\n"<<stringtemp[temp+rp[j].ch.size()];cin.get();
            if(ischinese(stringtemp[temp+rp[j].ch.size()]))isnew=1;
            }
        else{
            if((temp+rp[j].ch.size())==stringtemp.size()){
                if(ischinese(stringtemp[temp-1]))isnew=1;
            }            else
                if(ischinese(stringtemp[temp-1])||ischinese(stringtemp[temp+rp[j].ch.size()]))isnew=1;
        }
    }

    void autoreplace(){
        for(j=0;j<i;++j){
            //for(filej=0;filej<filei;++filej){//一行为单位
                stringtemp=rfile[filej];
                rfile[filej]="";
                while((temp=stringtemp.find(rp[j].ch))!=string::npos){//若并非找不到
                    //cout<<"temp:"<<temp<<endl;
                    ifisnew(j);//要先知道它是不是一个新字符串
                    if(isnew){donew();
                    //cout<<stringtemp<<endl;
                    continue;
                    }
                    doold(j);
                    //cout<<stringtemp<<endl;
                }
                rfile[filej]+=stringtemp;
            //}
        }
    }

    void donew(){
        //cout<<"new\n";
        while(ischinese(stringtemp[++temp]));
        rfile[filej]+=stringtemp.substr(0,temp);//cout<<rfile[filej]<<endl;
        stringtemp=stringtemp.substr(temp);//cout<<stringtemp<<endl;
    }

    void doold(int j){
        //cout<<"old\nstringtemp:"<<stringtemp<<endl<<temp+rp[j].ch.size()<<endl;
        stringtemp.replace(temp,rp[j].ch.size(),rp[j].en);
        //cout<<stringtemp<<endl;
        rfile[filej]+=stringtemp.substr(0,temp+rp[j].en.size());
        //cout<<rfile[filej]<<endl;
        stringtemp=stringtemp.substr(temp+rp[j].en.size());
    }

    void addcn(){
        //for(filej=0;filej<filei;++filej){
            stringsize=rfile[filej].size();
            for(tempj=0;tempj<stringsize;++tempj){
                if(rfile[filej][tempj]==';'){break;}//遇到注释标记直接跳出循环
                if(!inaddmode){//如果不是在截取中文模式
                    if(ischinese(rfile[filej][tempj])){//假如是英文和数字以外的字符(也就是中文了)
                        strstart=tempj;//这个变量用来储存中文字符串的开始位置
                        inaddmode=1;//进入截取中文状态
                    }
                }
                else{//若在截取中文模式
                    if(!ischinese(rfile[filej][tempj])){//且遇到英文的
                        addrecord();//提高可读性,一个函数解决
                        //cout<<"whatthefuck"<<rfile[filej]<<endl<<tempj;
                    }
                }
            }
                //还有一种情况,当循环结束但还是处于截取中文模式,就说明这段中文直到末尾
            if(inaddmode){
                addrecord();
                //cout<<"whatthefuck2"<<rfile[filej];
            }
        //}
    }

    void writeinfile(){
        ++i;
        ofile.open("set.ini");
        for(j=0;j<i;++j)
            ofile<<rp[j].ch<<" "<<rp[j].en<<endl;
        ofile.close();
    }

    void writeinrp(){
        newrp=new yoxi[i+1];
        for(j=0;j<i;++j){
            newrp[j]=rp[j];
        }
        delete []rp;
        newrp[i].ch=rfile[filej].substr(strstart,tempj-strstart);
        sprintf(newname,"a%d",i+1);
        newrp[i].en=newname;
        rp=newrp;
    }



jybox 2012-08-11 18:25
用C写这个该是有多么蛋痛啊

outman 2012-08-11 19:03
jybox:用C写这个该是有多么蛋痛啊 (2012-08-11 18:25) 

是C++

pdl 2012-08-11 19:32
用bison+flex自动生成多好。。。

jybox 2012-08-11 21:57
outman:是C++ (2012-08-11 19:03) 

明明是C风格




Powered by phpwind v8.7 Code ©2003-2011 phpwind
Time 0.048534 second(s),query:5 Gzip enabled