编译原理 第二次实验 语法分析 按照崔老师上午授课内容写出来框架

 

老师授课内容:

 

注意:

调用advance(),依次读取一个词法分析得到的结果,得到的结果形式为 (种别码,D)   其中D 可以为  +  -  *  /   数字  。

定义:

sym 得到的是每次取得结果   (   和  ,前面中间的值,即种别码。  种别码时string类型。

 

举例: 

以下程序用来判断是+  或者  -  

 

以下程序用来判断 *  或者 /

 

以下程序用来判断  (

 

以下程序用来判断  )

 

以下程序用来判断数字(注意数字不用管数值是多少)

 

以下程序用来报错:

 printf("Error!\n");
 exit(1);

 

 

程序框架1如下:

如果运行不了,可以试试框架2

#include<bits/stdc++.h>
#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<sstream>

using namespace std;

template <class Type> Type stringToNum(const string& str)
{
    istringstream iss(str);
    Type num;
    iss >> num;
    return num;
}

int num=0;
int sum=0;

ifstream infile("d.txt");//词法分析的结果或语法分析的输入
string str;//string变量进行字符识别
string sym; //指针
string sym1;
int temp=0;

//int expressionAnalysis();//表达式分析
//int termAnaysis();//项分析
//int factorAnalysis();//因子分析
//int advance();
int E();
int E_plus();
int T();
int T_plus();
int F();


int conterr=0;//记录错误
int lpnum=0;//记录左括号
int found;//提取字符串中指针的位置
string sym2;
int found1;
int flag=0;//记录往后移动一个指针SYM是否正确
string s;//用来保存要分析的字符串
struct _2tup
{
    string token;
    int id;
};

int advance() //SYM的移动
{
    if(!getline(infile,str)) //从文件中提取字符
    {
        return 0;
    }
//    cout<<str<<endl;
    s+=str;
//    cout<<s<<endl;
    found=str.find(',',0);
    found1=str.find(')',0);
//    cout<<found1<<endl;

    if(found==-1) //当为error的时候,没有‘,’
    {
        conterr++;
        return 0;
//        cout<<"语法错误 识别字符错误"<<endl;
//        return -1;
    }
    if(temp==1)
        sym1=sym;
    sym=str.substr(1,found-1);
    sym2=str.substr(found+1,found1-found-1);

    num=stringToNum<int>(sym2);
//    cout<<num<<endl;

    return 1;
}

int F()
{
 

}
int T_plus()
{
 
}
int T()
{

  

}

int E_plus()
{
  
}



int E()
{

    T();
    E_plus();

}
void yufafenxi()//语法分析
{
//    freopen("CON", "w", stdout);//结果在控制台上输出
//    flag=advance();
//    if(flag)-
//    {
    advance();
    E();
//    advance();
    if(strcmp(str.data(),"#")!=0)
    {
        printf("%s\n",s.data());
        printf("Error\n");
    }
    else
    {
        cout<<"OK:   "<<s<<endl;
    }
//    }
//    if(flag!=-1 && !conterr)
//    {
//    cout<<"正确:"<<s<<endl;
//    }

}



string instr;//输入符号串
int index;//当前输入符号读入字符的位置
char character;//全局变量字符,存放最新读入的字符
string token;//字符数组,存放已读入的字符序列
map<string, int> Symbol;//标识符集
map<string, int> Digit;//常数集
map<string, int> other;//other
map<string, int>::iterator ite;
const int len = 100;
string Reserve[len];//保留字表
map<string,int> type;
//void init_Reserve()  //构造保留字表的函数
//{
//    Reserve[1] = "begin";
//    Reserve[2] = "end";
//    Reserve[3] = "if";
//    Reserve[4] = "then";
//    Reserve[5] = "while";
//    Reserve[6] = "do";
//    Reserve[7] = "const";
//    Reserve[8] = "var";
//    Reserve[9] = "call";
//    Reserve[10] = "procedure";
//
//}
void getChar()  //读入一个字符
{
    character = instr[index++];
}
void getnbc()  //读入非空白字符
{
    while (character == ' ')
    {
        getChar();
    }
}
void concat()  //连接字符串
{
    token = token + character;
}
bool letter()  //判断是否为字母
{
    if ((character >= 'A'&&character <= 'Z') || (character >= 'a'&&character <= 'z'))
        return true;
    return false;
}
bool digit()  //判断是否为数字
{
    if (character >= '0'&&character <= '9')
        return true;
    return false;
}
void retract() //回退字符的函数
{
//    character = ' ';
    index--;
}
int reserve()  //匹配保留字符
{
    for (int i = 0; i < len; i++)
        if (Reserve[i] == token)
            return i;
    return -1;
}
void symbol()
{
    ite = Symbol.find(token);
    if (ite != Symbol.end())
    {
//        return ite->first;
        return ;
    }
    else
    {
        Symbol[token] = Symbol.size();
        return ;
//        return token;
    }
}
void constant()
{
    ite = Digit.find(token);
    if (ite != Digit.end())
    {
//        return ite->first;
        return ;
    }
    else
    {
        Digit[token] = Digit.size();
        return ;
//        return token;

    }
}
void Three()
{
    ite = other.find(token);
    if (ite != other.end())
    {
        return ;
//        return ite->first;
    }
    else
    {
        other[token] = other.size();
        return ;
//        return token;
    }
}
void error()
{
    cout << token << "\t-->\t该单词不存在" << endl;
}
//词法分析函数,逐个识别单词
string LexAnalyze()
{
    token = "";
    getChar();
    getnbc();
    string val;
//    int num = -1;
    if(character>='a'&&character<='z' || character>='A'&&character<='Z')
    {
        while (letter() || digit())  //为字母或数字
        {
            concat();//追加到token末尾

//            if(token=="odd")
//            {
//                getChar();
//                Three();
//                return ;
//            }
            getChar();//读取下一个字符
        }
        if(token=="odd")
        {
            getChar();
            Three();
            return 0;
        }
        retract();//回退一个字符
        {
//            val = symbol();//查看标识符表
            symbol();

        }
    }
    else if(character>='0' && character<='9')
    {
        int flag=0;
        while (character>='0' && character<='9' || character>='a' && character<='z' || character>='A' && character <='Z')
        {
            if(character>='0' && character<='9')
                concat();

            if(character>='a' && character<='z' || character>='A' && character <='Z')
            {
                concat();
                flag=1;
            }
            getChar();
        }
        if(flag==1)
        {
            error();
            return 0;
        }
        retract();
//        val = constant();//查看常数表
        constant();

    }
    else if(character=='<')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();
//返回<=符号
        }
        else if(character=='>')
        {
            concat();
            Three();
        }
        else
        {
            retract();
            Three();
//返回<符号
        }
    }
    else if(character=='>')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();
//返回>=符号
        }
        else
        {
            retract();
            Three();
//返回>符号
        }
    }
    else if(character=='=')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();
//返回==符号
        }
        else
        {
            retract();
            Three();
//返回=符号
        }
    }

    else if(character==':')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();

        }
        else
        {
            cout<<token<<endl;
            error();
            return 0;
        }
    }

    else if(character=='+')
    {
        concat();
        Three();
    }


    else if(character=='-')
    {
        concat();
        Three();
    }

    else if(character=='*')
    {
        concat();
        Three();
    }


    else if(character=='/')
    {
        concat();
        Three();
    }


    else if(character=='(')
    {
        concat();
        Three();
    }

    else if(character==')')
    {
        concat();
        Three();
    }

    else if(character==',')
    {
        concat();
        Three();
    }

    else if(character=='.')
    {
        concat();
        Three();
    }

    else if(character==';')
    {
        concat();
        Three();
    }

    else if(character=='#')
    {
        concat();
        return token;
    }
    else
    {
        error();
        return 0;
    }

    return token;

}
void show_table()
{
    cout << "\n==================" << "标识符" << "==================" << endl;
//    cout << "标识符\t\t类别编码\t表中位置" << endl;
    for (ite=Symbol.begin(); ite != Symbol.end(); ite++)
    {
//        int flag=0;
//        for (int i = 0; i < len; i++)
//        {
               cout<<Reserve[i]<<endl;
//            if (Reserve[i] == ite->first)
//            {
//                cout<<ite->first<<"是保留字"<<"   ";
//                cout << "("<<ite->first <<","<<ite->second<<")" << endl;
//                flag=1;
//                break;
//            }
//
//
//        }
//        if(flag==0)
//            cout << "("<<ite->first <<","<<ite->second<<")" << endl;

        map<string,int>::iterator iter;
        iter=type.find(ite->first);
        if(iter!=type.end())
            cout << "("<<iter->second <<","<<ite->second<<")" << endl;
        else
            cout << "("<<type.size() <<","<<ite->second<<")" << endl;
    }
    cout << "\n==================" << "常数表" << "==================" << endl;
//    cout << "常量值\t\t类别编码\t表中位置" << endl;
    for (ite = Digit.begin(); ite != Digit.end(); ite++)
    {
//        cout << "("<<ite->first <<","<<ite->second<<")" << endl;
        map<string,int>::iterator iter;
        iter=type.find(ite->first);
//        if(iter!=type.end())
//            cout << "("<<iter->second <<","<<ite->second<<")" << endl;
//        else
        cout << "("<<type.size()-1 <<","<<ite->second<<")" << endl;
    }
    cout << "\n==================" << "算符、界符" << "==================" << endl;
    for (ite = other.begin(); ite != other.end(); ite++)
    {
//        cout << "("<<ite->first <<","<<ite->second<<")" << endl;
        map<string,int>::iterator iter;
        iter=type.find(ite->first);
        cout << "("<<iter->second <<","<<ite->second<<")" << endl;
//           cout<<iter->second<<endl;
    }
}
int main()
{
//    clock_t start,finish;
//    double totaltime;
//    start=clock();


    type["begin"]=type.size();
    type["end"]=type.size();
    type["if"]=type.size();
    type["then"]=type.size();
    type["while"]=type.size();
    type["do"]=type.size();
    type["const"]=type.size();
    type["var"]=type.size();
    type["call"]=type.size();
    type["procedure"]=type.size();
    type["+"]=type.size();
    type["-"]=type.size();
    type["*"]=type.size();
    type["/"]=type.size();
    type["odd"]=type.size();
    type["="]=type.size();
    type["<>"]=type.size();
    type["<"]=type.size();
    type[">"]=type.size();
    type["<="]=type.size();
    type[">="]=type.size();
    type[":="]=type.size();
    type["("]=type.size();
    type[")"]=type.size();
    type[","]=type.size();
    type["."]=type.size();
    type[";"]=type.size();
    type["常数"]=type.size();
    type["标识符"]=type.size();



//    init_Reserve();//保留字表初始化
    Symbol.clear();//标识符集初始化
    Digit.clear();//常数集初始化
    index = 0;
    character = ' ';
    token = "";
    cout << "请输入待词法分析的源程序代码:输入文件结束符结束输入\n" << endl;
    //源程序代码输入处理
//    instr="var a,b,c; a:=1; b:=2; c:=a+b";


    char ch[1000];
    string ins;
//    printf("%d\n",gets(ch));
//    printf("\n%d",&ch[1]);
//    cout<<gets(ch)<<endl;
    while(gets(ch))
    {
        FILE *fp;
//        char str[1000];
        map<string,int>::iterator iter;
        if((fp=fopen("d.txt","w"))==NULL)
        {
            printf("error occur!\n");
            exit(1);
        }
        if((fp=fopen("d.txt","a"))==NULL)
        {
            printf("error occur!\n");
            exit(1);
        }

//        ins=ch;


        instr=ch;
        index=0;
        while (index < instr.size())
        {
            char* str=(char*)LexAnalyze().data();
//                    fprintf(fp,"%s\n",str);
//            cout<<str<<endl;
            if(strcmp(str,"#")==0)
            {
//                printf("*");
                fprintf(fp,"%s",str);
            }
            else
            {
                iter=type.find(str);
                if(iter!=type.end())

//                if(index==instr.size())
                    fprintf(fp,"(%d,%s)\n",iter->second,str);
//                else
//                    fprintf(fp,"(%d,%s)\n",iter->second,str);
                else
                {
                    iter=Digit.find(str);
                    if(iter!=Digit.end())

//                if(index==instr.size())
                        fprintf(fp,"(28,%s)\n",str);
//                else
//                    fprintf(fp,"(28,%s)\n",str);


                }
            }
        }

        fclose(fp);


//        cout<<instr<<endl;
        memset(ch,0,sizeof(ch));
    }
    yufafenxi();

//    cout<<instr<<endl;
//    string in;
//    while (cin >> in&&in != "@")
//    {
//        instr = instr + " " + in;
//    }
    //识别二元组初始化
//    while (index < instr.size())
//    {
//        LexAnalyze();
//    }
    //展示构造的各种词汇表
    show_table();

//    finish=clock();
//    totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
//    cout<<totaltime<<endl;
//    //system("pause");
    return 0;

}

 

框架2

//#include<bits/stdc++.h>
#include <fstream>
#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<sstream>

using namespace std;

template <class Type> Type stringToNum(const string& str)
{
    istringstream iss(str);
    Type num;
    iss >> num;
    return num;
}

int num=0;
int sum=0;

ifstream infile("d.txt");//词法分析的结果或语法分析的输入
string str;//string变量进行字符识别
string sym; //指针
string sym1;
int temp=0;

//int expressionAnalysis();//表达式分析
//int termAnaysis();//项分析
//int factorAnalysis();//因子分析
//int advance();
int E();
int E_plus();
int T();
int T_plus();
int F();


int conterr=0;//记录错误
int lpnum=0;//记录左括号
int found;//提取字符串中指针的位置
string sym2;
int found1;
int flag=0;//记录往后移动一个指针SYM是否正确
string s;//用来保存要分析的字符串
struct _2tup
{
    string token;
    int id;
};

int advance() //SYM的移动
{
    if(!getline(infile,str)) //从文件中提取字符
    {
        return 0;
    }
//    cout<<str<<endl;
    s+=str;
//    cout<<s<<endl;
    found=str.find(',',0);
    found1=str.find(')',0);
//    cout<<found1<<endl;

    if(found==-1) //当为error的时候,没有‘,’
    {
        conterr++;
        return 0;
//        cout<<"语法错误 识别字符错误"<<endl;
//        return -1;
    }
    if(temp==1)
        sym1=sym;
    sym=str.substr(1,found-1);
    sym2=str.substr(found+1,found1-found-1);

    num=stringToNum<int>(sym2);
//    cout<<num<<endl;

    return 1;
}

int F()
{


}
int T_plus()
{

}
int T()
{



}

int E_plus()
{

}



int E()
{

    T();
    E_plus();

}
void yufafenxi()//语法分析
{
//    freopen("CON", "w", stdout);//结果在控制台上输出
//    flag=advance();
//    if(flag)-
//    {
    advance();
    E();
//    advance();
    if(strcmp(str.data(),"#")!=0)
    {
        printf("%s\n",s.data());
        printf("Error\n");
    }
    else
    {
        cout<<"OK:   "<<s<<endl;
    }
//    }
//    if(flag!=-1 && !conterr)
//    {
//    cout<<"正确:"<<s<<endl;
//    }

}



string instr;//输入符号串
int index;//当前输入符号读入字符的位置
char character;//全局变量字符,存放最新读入的字符
string token;//字符数组,存放已读入的字符序列
map<string, int> Symbol;//标识符集
map<string, int> Digit;//常数集
map<string, int> other;//other
map<string, int>::iterator ite;
const int len = 100;
string Reserve[len];//保留字表
map<string,int> type;
//void init_Reserve()  //构造保留字表的函数
//{
//    Reserve[1] = "begin";
//    Reserve[2] = "end";
//    Reserve[3] = "if";
//    Reserve[4] = "then";
//    Reserve[5] = "while";
//    Reserve[6] = "do";
//    Reserve[7] = "const";
//    Reserve[8] = "var";
//    Reserve[9] = "call";
//    Reserve[10] = "procedure";
//
//}
void getChar()  //读入一个字符
{
    character = instr[index++];
}
void getnbc()  //读入非空白字符
{
    while (character == ' ')
    {
        getChar();
    }
}
void concat()  //连接字符串
{
    token = token + character;
}
bool letter()  //判断是否为字母
{
    if ((character >= 'A'&&character <= 'Z') || (character >= 'a'&&character <= 'z'))
        return true;
    return false;
}
bool digit()  //判断是否为数字
{
    if (character >= '0'&&character <= '9')
        return true;
    return false;
}
void retract() //回退字符的函数
{
//    character = ' ';
    index--;
}
int reserve()  //匹配保留字符
{
    for (int i = 0; i < len; i++)
        if (Reserve[i] == token)
            return i;
    return -1;
}
void symbol()
{
    ite = Symbol.find(token);
    if (ite != Symbol.end())
    {
//        return ite->first;
        return ;
    }
    else
    {
        Symbol[token] = Symbol.size();
        return ;
//        return token;
    }
}
void constant()
{
    ite = Digit.find(token);
    if (ite != Digit.end())
    {
//        return ite->first;
        return ;
    }
    else
    {
        Digit[token] = Digit.size();
        return ;
//        return token;

    }
}
void Three()
{
    ite = other.find(token);
    if (ite != other.end())
    {
        return ;
//        return ite->first;
    }
    else
    {
        other[token] = other.size();
        return ;
//        return token;
    }
}
void error()
{
    cout << token << "\t-->\t该单词不存在" << endl;
}
//词法分析函数,逐个识别单词
string LexAnalyze()
{
    token = "";
    getChar();
    getnbc();
    string val;
//    int num = -1;
    if(character>='a'&&character<='z' || character>='A'&&character<='Z')
    {
        while (letter() || digit())  //为字母或数字
        {
            concat();//追加到token末尾

//            if(token=="odd")
//            {
//                getChar();
//                Three();
//                return ;
//            }
            getChar();//读取下一个字符
        }
        if(token=="odd")
        {
            getChar();
            Three();
            return 0;
        }
        retract();//回退一个字符
        {
//            val = symbol();//查看标识符表
            symbol();

        }
    }
    else if(character>='0' && character<='9')
    {
        int flag=0;
        while (character>='0' && character<='9' || character>='a' && character<='z' || character>='A' && character <='Z')
        {
            if(character>='0' && character<='9')
                concat();

            if(character>='a' && character<='z' || character>='A' && character <='Z')
            {
                concat();
                flag=1;
            }
            getChar();
        }
        if(flag==1)
        {
            error();
            return 0;
        }
        retract();
//        val = constant();//查看常数表
        constant();

    }
    else if(character=='<')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();
//返回<=符号
        }
        else if(character=='>')
        {
            concat();
            Three();
        }
        else
        {
            retract();
            Three();
//返回<符号
        }
    }
    else if(character=='>')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();
//返回>=符号
        }
        else
        {
            retract();
            Three();
//返回>符号
        }
    }
    else if(character=='=')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();
//返回==符号
        }
        else
        {
            retract();
            Three();
//返回=符号
        }
    }

    else if(character==':')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();

        }
        else
        {
            cout<<token<<endl;
            error();
            return 0;
        }
    }

    else if(character=='+')
    {
        concat();
        Three();
    }


    else if(character=='-')
    {
        concat();
        Three();
    }

    else if(character=='*')
    {
        concat();
        Three();
    }


    else if(character=='/')
    {
        concat();
        Three();
    }


    else if(character=='(')
    {
        concat();
        Three();
    }

    else if(character==')')
    {
        concat();
        Three();
    }

    else if(character==',')
    {
        concat();
        Three();
    }

    else if(character=='.')
    {
        concat();
        Three();
    }

    else if(character==';')
    {
        concat();
        Three();
    }

    else if(character=='#')
    {
        concat();
        return token;
    }
    else
    {
        error();
        return 0;
    }

    return token;

}
void show_table()
{
    cout << "\n==================" << "标识符" << "==================" << endl;
//    cout << "标识符\t\t类别编码\t表中位置" << endl;
    for (ite=Symbol.begin(); ite != Symbol.end(); ite++)
    {
//        int flag=0;
//        for (int i = 0; i < len; i++)
//        {
//               cout<<Reserve[i]<<endl;
//            if (Reserve[i] == ite->first)
//            {
//                cout<<ite->first<<"是保留字"<<"   ";
//                cout << "("<<ite->first <<","<<ite->second<<")" << endl;
//                flag=1;
//                break;
//            }
//
//
//        }
//        if(flag==0)
//            cout << "("<<ite->first <<","<<ite->second<<")" << endl;

        map<string,int>::iterator iter;
        iter=type.find(ite->first);
        if(iter!=type.end())
            cout << "("<<iter->second <<","<<ite->second<<")" << endl;
        else
            cout << "("<<type.size() <<","<<ite->second<<")" << endl;
    }
    cout << "\n==================" << "常数表" << "==================" << endl;
//    cout << "常量值\t\t类别编码\t表中位置" << endl;
    for (ite = Digit.begin(); ite != Digit.end(); ite++)
    {
//        cout << "("<<ite->first <<","<<ite->second<<")" << endl;
        map<string,int>::iterator iter;
        iter=type.find(ite->first);
//        if(iter!=type.end())
//            cout << "("<<iter->second <<","<<ite->second<<")" << endl;
//        else
        cout << "("<<type.size()-1 <<","<<ite->second<<")" << endl;
    }
    cout << "\n==================" << "算符、界符" << "==================" << endl;
    for (ite = other.begin(); ite != other.end(); ite++)
    {
//        cout << "("<<ite->first <<","<<ite->second<<")" << endl;
        map<string,int>::iterator iter;
        iter=type.find(ite->first);
        cout << "("<<iter->second <<","<<ite->second<<")" << endl;
//           cout<<iter->second<<endl;
    }
}
int main()
{
//    clock_t start,finish;
//    double totaltime;
//    start=clock();


    type["begin"]=type.size();
    type["end"]=type.size();
    type["if"]=type.size();
    type["then"]=type.size();
    type["while"]=type.size();
    type["do"]=type.size();
    type["const"]=type.size();
    type["var"]=type.size();
    type["call"]=type.size();
    type["procedure"]=type.size();
    type["+"]=type.size();
    type["-"]=type.size();
    type["*"]=type.size();
    type["/"]=type.size();
    type["odd"]=type.size();
    type["="]=type.size();
    type["<>"]=type.size();
    type["<"]=type.size();
    type[">"]=type.size();
    type["<="]=type.size();
    type[">="]=type.size();
    type[":="]=type.size();
    type["("]=type.size();
    type[")"]=type.size();
    type[","]=type.size();
    type["."]=type.size();
    type[";"]=type.size();
    type["常数"]=type.size();
    type["标识符"]=type.size();



//    init_Reserve();//保留字表初始化
    Symbol.clear();//标识符集初始化
    Digit.clear();//常数集初始化
    index = 0;
    character = ' ';
    token = "";
    cout << "请输入待词法分析的源程序代码:输入文件结束符结束输入\n" << endl;
    //源程序代码输入处理
//    instr="var a,b,c; a:=1; b:=2; c:=a+b";


    char ch[1000];
    string ins;
//    printf("%d\n",gets(ch));
//    printf("\n%d",&ch[1]);
//    cout<<gets(ch)<<endl;
    while(gets(ch))
    {
        FILE *fp;
//        char str[1000];
        map<string,int>::iterator iter;
        if((fp=fopen("d.txt","w"))==NULL)
        {
            printf("error occur!\n");
            exit(1);
        }
        if((fp=fopen("d.txt","a"))==NULL)
        {
            printf("error occur!\n");
            exit(1);
        }

//        ins=ch;


        instr=ch;
        index=0;
        while (index < instr.size())
        {
            char* str=(char*)LexAnalyze().data();
//                    fprintf(fp,"%s\n",str);
//            cout<<str<<endl;
            if(strcmp(str,"#")==0)
            {
//                printf("*");
                fprintf(fp,"%s",str);
            }
            else
            {
                iter=type.find(str);
                if(iter!=type.end())

//                if(index==instr.size())
                    fprintf(fp,"(%d,%s)\n",iter->second,str);
//                else
//                    fprintf(fp,"(%d,%s)\n",iter->second,str);
                else
                {
                    iter=Digit.find(str);
                    if(iter!=Digit.end())

//                if(index==instr.size())
                        fprintf(fp,"(28,%s)\n",str);
//                else
//                    fprintf(fp,"(28,%s)\n",str);


                }
            }
        }

        fclose(fp);


//        cout<<instr<<endl;
        memset(ch,0,sizeof(ch));
    }
    yufafenxi();

//    cout<<instr<<endl;
//    string in;
//    while (cin >> in&&in != "@")
//    {
//        instr = instr + " " + in;
//    }
    //识别二元组初始化
//    while (index < instr.size())
//    {
//        LexAnalyze();
//    }
    //展示构造的各种词汇表
    show_table();

//    finish=clock();
//    totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
//    cout<<totaltime<<endl;
//    //system("pause");
    return 0;

}

 

 

词法分析得到的结果存放在同级目录  d.txt 中。 

 

 

 

程序:

//#include<bits/stdc++.h>
#include <fstream>
#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<sstream>

using namespace std;

template <class Type> Type stringToNum(const string& str)
{
    istringstream iss(str);
    Type num;
    iss >> num;
    return num;
}

int num=0;
int sum=0;

ifstream infile("d.txt");//词法分析的结果或语法分析的输入
string str;//string变量进行字符识别
string sym; //指针
string sym1;
int temp=0;

//int expressionAnalysis();//表达式分析
//int termAnaysis();//项分析
//int factorAnalysis();//因子分析
//int advance();
int E();
int E_plus();
int T();
int T_plus();
int F();


int conterr=0;//记录错误
int lpnum=0;//记录左括号
int found;//提取字符串中指针的位置
string sym2;
int found1;
int flag=0;//记录往后移动一个指针SYM是否正确
string s;//用来保存要分析的字符串
struct _2tup
{
    string token;
    int id;
};

int advance() //SYM的移动
{
    if(!getline(infile,str)) //从文件中提取字符
    {
        return 0;
    }
//    cout<<str<<endl;
    s+=str;
//    cout<<s<<endl;
    found=str.find(',',0);
    found1=str.find(')',0);
//    cout<<found1<<endl;

    if(found==-1) //当为error的时候,没有‘,’
    {
        conterr++;
        return 0;
//        cout<<"语法错误 识别字符错误"<<endl;
//        return -1;
    }
    if(temp==1)
        sym1=sym;
    sym=str.substr(1,found-1);
    sym2=str.substr(found+1,found1-found-1);

    num=stringToNum<int>(sym2);
//    cout<<num<<endl;

    return 1;
}

int F()
{
    if(sym=="28")
    {
        advance();
    }
    else
    {
        if(sym=="23")
        {
            advance();
            E();
            if(sym=="24")
            {
                advance();
            }
            else
            {
                printf("Error!\n");
                exit(1);
            }
        }
        else
        {
            printf("Error!\n");
            exit(1);
        }

    }
    return 0;

}
int T_plus()
{
    if(sym=="13" || sym=="14") // 如果是 *  /
    {
        advance();
        T();
        E_plus();
    }
}
int T()
{

   F();
   T_plus();

}

int E_plus()
{
    if(sym=="11" || sym=="12")  // 如果是+ 或者 -
    {
        advance();
        T();
        E_plus();
    }
}



int E()
{

    T();
    E_plus();

}
void yufafenxi()//语法分析
{
//    freopen("CON", "w", stdout);//结果在控制台上输出
//    flag=advance();
//    if(flag)-
//    {
    advance();
    E();
//    advance();
    if(strcmp(str.data(),"#")!=0)
    {
        printf("%s\n",s.data());
        printf("Error\n");
    }
    else
    {
        cout<<"OK:   "<<s<<endl;
    }
//    }
//    if(flag!=-1 && !conterr)
//    {
//    cout<<"正确:"<<s<<endl;
//    }

}



string instr;//输入符号串
int index;//当前输入符号读入字符的位置
char character;//全局变量字符,存放最新读入的字符
string token;//字符数组,存放已读入的字符序列
map<string, int> Symbol;//标识符集
map<string, int> Digit;//常数集
map<string, int> other;//other
map<string, int>::iterator ite;
const int len = 100;
string Reserve[len];//保留字表
map<string,int> type;
//void init_Reserve()  //构造保留字表的函数
//{
//    Reserve[1] = "begin";
//    Reserve[2] = "end";
//    Reserve[3] = "if";
//    Reserve[4] = "then";
//    Reserve[5] = "while";
//    Reserve[6] = "do";
//    Reserve[7] = "const";
//    Reserve[8] = "var";
//    Reserve[9] = "call";
//    Reserve[10] = "procedure";
//
//}
void getChar()  //读入一个字符
{
    character = instr[index++];
}
void getnbc()  //读入非空白字符
{
    while (character == ' ')
    {
        getChar();
    }
}
void concat()  //连接字符串
{
    token = token + character;
}
bool letter()  //判断是否为字母
{
    if ((character >= 'A'&&character <= 'Z') || (character >= 'a'&&character <= 'z'))
        return true;
    return false;
}
bool digit()  //判断是否为数字
{
    if (character >= '0'&&character <= '9')
        return true;
    return false;
}
void retract() //回退字符的函数
{
//    character = ' ';
    index--;
}
int reserve()  //匹配保留字符
{
    for (int i = 0; i < len; i++)
        if (Reserve[i] == token)
            return i;
    return -1;
}
void symbol()
{
    ite = Symbol.find(token);
    if (ite != Symbol.end())
    {
//        return ite->first;
        return ;
    }
    else
    {
        Symbol[token] = Symbol.size();
        return ;
//        return token;
    }
}
void constant()
{
    ite = Digit.find(token);
    if (ite != Digit.end())
    {
//        return ite->first;
        return ;
    }
    else
    {
        Digit[token] = Digit.size();
        return ;
//        return token;

    }
}
void Three()
{
    ite = other.find(token);
    if (ite != other.end())
    {
        return ;
//        return ite->first;
    }
    else
    {
        other[token] = other.size();
        return ;
//        return token;
    }
}
void error()
{
    cout << token << "\t-->\t该单词不存在" << endl;
}
//词法分析函数,逐个识别单词
string LexAnalyze()
{
    token = "";
    getChar();
    getnbc();
    string val;
//    int num = -1;
    if(character>='a'&&character<='z' || character>='A'&&character<='Z')
    {
        while (letter() || digit())  //为字母或数字
        {
            concat();//追加到token末尾

//            if(token=="odd")
//            {
//                getChar();
//                Three();
//                return ;
//            }
            getChar();//读取下一个字符
        }
        if(token=="odd")
        {
            getChar();
            Three();
            return 0;
        }
        retract();//回退一个字符
        {
//            val = symbol();//查看标识符表
            symbol();

        }
    }
    else if(character>='0' && character<='9')
    {
        int flag=0;
        while (character>='0' && character<='9' || character>='a' && character<='z' || character>='A' && character <='Z')
        {
            if(character>='0' && character<='9')
                concat();

            if(character>='a' && character<='z' || character>='A' && character <='Z')
            {
                concat();
                flag=1;
            }
            getChar();
        }
        if(flag==1)
        {
            error();
            return 0;
        }
        retract();
//        val = constant();//查看常数表
        constant();

    }
    else if(character=='<')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();
//返回<=符号
        }
        else if(character=='>')
        {
            concat();
            Three();
        }
        else
        {
            retract();
            Three();
//返回<符号
        }
    }
    else if(character=='>')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();
//返回>=符号
        }
        else
        {
            retract();
            Three();
//返回>符号
        }
    }
    else if(character=='=')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();
//返回==符号
        }
        else
        {
            retract();
            Three();
//返回=符号
        }
    }

    else if(character==':')
    {
        concat();
        getChar();
        if (character == '=')
        {
            concat();
            Three();

        }
        else
        {
            cout<<token<<endl;
            error();
            return 0;
        }
    }

    else if(character=='+')
    {
        concat();
        Three();
    }


    else if(character=='-')
    {
        concat();
        Three();
    }

    else if(character=='*')
    {
        concat();
        Three();
    }


    else if(character=='/')
    {
        concat();
        Three();
    }


    else if(character=='(')
    {
        concat();
        Three();
    }

    else if(character==')')
    {
        concat();
        Three();
    }

    else if(character==',')
    {
        concat();
        Three();
    }

    else if(character=='.')
    {
        concat();
        Three();
    }

    else if(character==';')
    {
        concat();
        Three();
    }

    else if(character=='#')
    {
        concat();
        return token;
    }
    else
    {
        error();
        return 0;
    }

    return token;

}
void show_table()
{
    cout << "\n==================" << "标识符" << "==================" << endl;
//    cout << "标识符\t\t类别编码\t表中位置" << endl;
    for (ite=Symbol.begin(); ite != Symbol.end(); ite++)
    {
//        int flag=0;
//        for (int i = 0; i < len; i++)
//        {
//               cout<<Reserve[i]<<endl;
//            if (Reserve[i] == ite->first)
//            {
//                cout<<ite->first<<"是保留字"<<"   ";
//                cout << "("<<ite->first <<","<<ite->second<<")" << endl;
//                flag=1;
//                break;
//            }
//
//
//        }
//        if(flag==0)
//            cout << "("<<ite->first <<","<<ite->second<<")" << endl;

        map<string,int>::iterator iter;
        iter=type.find(ite->first);
        if(iter!=type.end())
            cout << "("<<iter->second <<","<<ite->second<<")" << endl;
        else
            cout << "("<<type.size() <<","<<ite->second<<")" << endl;
    }
    cout << "\n==================" << "常数表" << "==================" << endl;
//    cout << "常量值\t\t类别编码\t表中位置" << endl;
    for (ite = Digit.begin(); ite != Digit.end(); ite++)
    {
//        cout << "("<<ite->first <<","<<ite->second<<")" << endl;
        map<string,int>::iterator iter;
        iter=type.find(ite->first);
//        if(iter!=type.end())
//            cout << "("<<iter->second <<","<<ite->second<<")" << endl;
//        else
        cout << "("<<type.size()-1 <<","<<ite->second<<")" << endl;
    }
    cout << "\n==================" << "算符、界符" << "==================" << endl;
    for (ite = other.begin(); ite != other.end(); ite++)
    {
//        cout << "("<<ite->first <<","<<ite->second<<")" << endl;
        map<string,int>::iterator iter;
        iter=type.find(ite->first);
        cout << "("<<iter->second <<","<<ite->second<<")" << endl;
//           cout<<iter->second<<endl;
    }
}
int main()
{
//    clock_t start,finish;
//    double totaltime;
//    start=clock();


    type["begin"]=type.size();
    type["end"]=type.size();
    type["if"]=type.size();
    type["then"]=type.size();
    type["while"]=type.size();
    type["do"]=type.size();
    type["const"]=type.size();
    type["var"]=type.size();
    type["call"]=type.size();
    type["procedure"]=type.size();
    type["+"]=type.size();
    type["-"]=type.size();
    type["*"]=type.size();
    type["/"]=type.size();
    type["odd"]=type.size();
    type["="]=type.size();
    type["<>"]=type.size();
    type["<"]=type.size();
    type[">"]=type.size();
    type["<="]=type.size();
    type[">="]=type.size();
    type[":="]=type.size();
    type["("]=type.size();
    type[")"]=type.size();
    type[","]=type.size();
    type["."]=type.size();
    type[";"]=type.size();
    type["常数"]=type.size();
    type["标识符"]=type.size();



//    init_Reserve();//保留字表初始化
    Symbol.clear();//标识符集初始化
    Digit.clear();//常数集初始化
    index = 0;
    character = ' ';
    token = "";
    cout << "请输入待词法分析的源程序代码:输入文件结束符结束输入\n" << endl;
    //源程序代码输入处理
//    instr="var a,b,c; a:=1; b:=2; c:=a+b";


    char ch[1000];
    string ins;
//    printf("%d\n",gets(ch));
//    printf("\n%d",&ch[1]);
//    cout<<gets(ch)<<endl;
    while(gets(ch))
    {
        FILE *fp;
//        char str[1000];
        map<string,int>::iterator iter;
        if((fp=fopen("d.txt","w"))==NULL)
        {
            printf("error occur!\n");
            exit(1);
        }
        if((fp=fopen("d.txt","a"))==NULL)
        {
            printf("error occur!\n");
            exit(1);
        }

//        ins=ch;


        instr=ch;
        index=0;
        while (index < instr.size())
        {
            char* str=(char*)LexAnalyze().data();
//                    fprintf(fp,"%s\n",str);
//            cout<<str<<endl;
            if(strcmp(str,"#")==0)
            {
//                printf("*");
                fprintf(fp,"%s",str);
            }
            else
            {
                iter=type.find(str);
                if(iter!=type.end())

//                if(index==instr.size())
                    fprintf(fp,"(%d,%s)\n",iter->second,str);
//                else
//                    fprintf(fp,"(%d,%s)\n",iter->second,str);
                else
                {
                    iter=Digit.find(str);
                    if(iter!=Digit.end())

//                if(index==instr.size())
                        fprintf(fp,"(28,%s)\n",str);
//                else
//                    fprintf(fp,"(28,%s)\n",str);


                }
            }
        }

        fclose(fp);


//        cout<<instr<<endl;
        memset(ch,0,sizeof(ch));
    }
    yufafenxi();

//    cout<<instr<<endl;
//    string in;
//    while (cin >> in&&in != "@")
//    {
//        instr = instr + " " + in;
//    }
    //识别二元组初始化
//    while (index < instr.size())
//    {
//        LexAnalyze();
//    }
    //展示构造的各种词汇表
    show_table();

//    finish=clock();
//    totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
//    cout<<totaltime<<endl;
//    //system("pause");
    return 0;

}

 

 

要求实现以下效果:

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿的探索之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值