编译原理实验课

本人没咋学编译原理,能力有限,写的不好轻点喷,大佬路过的话,那你就路过就好

东大编译原理实验课原题,24年

1. 基本题:简单的扫描器设计

【问题描述】

熟悉并实现一个简单的扫描器,设计扫描器的自动机;设计翻译、生成Token的算法;编写代码并上机调试运行通过。

要求扫描器可识别的单词包括:关键字、界符、标识符和常整形数。

其中关键字表、界符表、标识符表、常整数表如下:(表中没有的关键字、界符等可以接着编号继续扩展)
在这里插入图片描述
【输入形式】源程序文件

【输出形式】

相应单词的Token序列;

标识符表,常数表。

【样例输入】

x10=x+y1*120+10;

【样例输出】

注意每行输出最后没有多余空格,最后一行输出后不换行。

Token :(I 1)(P 11)(I 2)(P 8)(I 3)(P 9)(C 1)(P 8)(C 2)(P 13)
I :x10 x y1
C :120 10

大体思路

我这里用了unordered_map来对应存<string,int> ,但是unordered_map他存进去后的顺序是胡乱的,不利于输出,我就直接存到vector里输出了,建议可以用pair<string,int> 方便点。
然后就是把想到的一些关键字,界符什么的初始化一下。
文件输入输出就上网一查,很多用法都有,我这里用了一种比较方便的。

从文本里一行一行的读入数据,存到一个string变量里,然后就对这个string从头到尾跑一遍,分三种情况,第一种是界符,如果当前字符是界符,那就再看看下一个字母是不是+,=这样的能够满足==,++,–这样的符号。第二种情况就是第一个字母为数字,这种呢就要么是标识符,要么就是整数了,分情况讨论就行。第三种就是第一个字母是字母,那这种就是要么关键字,要么标识符了
过验收的代码(文件输入输出)
里边的小注释是我用来debug的,一些没用到的变量是给第二题的,第二题题目看着怪怪的,不想写了,也懒得改了

#include<iostream>
#include<unordered_map>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<fstream>
using namespace std;
unordered_map<string,int> keyK;//这个无序是胡乱排序,也不按照自己输入的顺序,后来知道了懒得改了,直接套个vector输出吧
unordered_map<string,int> keyP;
unordered_map<string,int> keyI;
unordered_map<string,int> keyC1;
unordered_map<string,int> keyC2;
unordered_map<string,int> keyCT;
unordered_map<string,int> keyST;
vector<string> I;
vector<string> C1;
vector<string> C2;
vector<string> CT;
vector<string> ST;
int idxI=1,idxC1=1,idxC2=1,idxCT=1,idxST=1;
int kind(char ch)
{
    if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return 1;
    if (ch>='0'&&ch<='9') return 2;
    if (ch=='-'||ch=='/'||ch=='('||ch==')'||ch=='='||ch=='<'||ch=='>'||ch=='+'||ch=='*'||ch==','||ch==';'||ch=='{'||ch=='}'||ch=='"') return 3;
    return 0;
}
void init()
{
    keyK["int"]=1,keyK["void"]=2,keyK["break"]=3,keyK["float"]=4,keyK["while"]=5;
    keyK["do"]=6,keyK["struct"]=7,keyK["const"]=8,keyK["case"]=9,keyK["for"]=10;
    keyK["return"]=11,keyK["if"]=12,keyK["default"]=13,keyK["else"]=14;
    keyK["long"]=15,keyK["short"]=16,keyK["double"]=17,keyK["char"]=18;
    keyK["unsigned"]=19,keyK["signed"]=20,keyK["union"]=21,keyK["goto"]=22;
    keyK["switch"]=23,keyK["continue"]=24,keyK["typedef"]=25,keyK["cout"]=26;
    keyK["cin"]=27,keyK["main"]=28,keyK["printf"]=29,keyK["scanf"]=30;

    keyP["-"]=1,keyP["/"]=2,keyP["("]=3,keyP[")"]=4,keyP["=="]=5,keyP["<="]=6;
    keyP["<"]=7,keyP["+"]=8,keyP["*"]=9,keyP[">"]=10,keyP["="]=11,keyP[","]=12;
    keyP[";"]=13,keyP["++"]=14,keyP["{"]=15,keyP["}"]=16,keyP["["]=17,keyP["]"]=18;

}
int main()
{
    init();
    //for (auto i:keyK) cout<<i.first<<" "<<i.second<<"\n";
    //for (auto i:keyP) cout<<i.first<<" "<<i.second<<"\n";

    ifstream infile;
    infile.open("data2.txt",ios::in);
    if (!infile.is_open())
    {
        printf("Not found file!\n");
        return 0;
    }
    cout<<"Token :";
    string input;
    while(getline(infile,input))
    {
        for (int i=0;i<(int)input.size();i++)
        {
            string tmp;
            //cout<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";
            if (kind(input[i])==3) {
                //cout<<"i=P"<<i<<" ";
                string tt;
                if (input[i+1]=='='||input[i+1]=='+') {
                    tt+=input[i];
                    tt+=input[i+1];
                    cout<<"(P "<<keyP[tt]<<")";
                    i++;
                }
                else {
                    tt+=input[i];
                    cout<<"(P "<<keyP[tt]<<")";
                }
            }
            else if (kind(input[i])==2) {
                //cout<<"i=C"<<i<<" ";
                bool flag=false;
                while (kind(input[i])!=3) {
                    if (kind(input[i])==1) flag=true;
                    tmp+=input[i];
                    i++;
                }
                i--;
                if (keyI.find(tmp)!=keyI.end()) {
                    cout<<"(I "<<keyI[tmp]<<")";
                }
                else if (keyC1.find(tmp)!=keyC1.end()) {
                    cout<<"(C1 "<<keyC1[tmp]<<")";
                }
                else {
                    if (flag) {
                        keyI[tmp]=idxI;
                        I.push_back(tmp);
                        cout<<"(I "<<idxI<<")";
                        idxI++;
                    }
                    else {
                        keyC1[tmp]=idxC1;
                        C1.push_back(tmp);
                        cout<<"(C1 "<<idxC1<<")";
                        idxC1++;
                    }
                }
            }
            else if (kind(input[i])==1) {
                //cout<<"i=K"<<i<<" ";
                bool Find=false;
                while (kind(input[i])!=3) {
                    tmp+=input[i];
                    if (keyK.find(tmp)!=keyK.end()) {
                        Find=true;
                        cout<<"(K "<<keyK[tmp]<<")";
                        break;
                    }
                    i++;
                }
                if (Find) continue;
                i--;
                if (keyK.find(tmp)!=keyK.end()) {
                    cout<<"(K "<<keyK[tmp]<<")";
                }
                else if (keyI.find(tmp)!=keyI.end()) {
                    cout<<"(I "<<keyI[tmp]<<")";
                }
                else {
                    keyI[tmp]=idxI;
                    I.push_back(tmp);
                    cout<<"(I "<<idxI<<")";
                    idxI++;
                }
            }
            //cout<<"2 "<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";
        }
    }
    cout<<"\nI :";
    bool flag=false;
    for (auto i:I) {
        if (!flag) flag=true;
        else cout<<" ";
        cout<<i;
    }
    cout<<"\n";
    cout<<"C1 :";
    flag=false;
    for (auto i:C1) {
        if (!flag) flag=true;
        else cout<<" ";
        cout<<i;
    }
    return 0;
}

都能过测试点的代码

#include<iostream>
#include<unordered_map>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<fstream>
using namespace std;
unordered_map<string,int> keyK;//这个无序是胡乱排序,也不按照自己输入的顺序,后来知道了懒得改了,直接套个vector输出吧
unordered_map<string,int> keyP;
unordered_map<string,int> keyI;
unordered_map<string,int> keyC;
vector<string> I;
vector<string> C;
int idxI=1,idxC=1;

vector<pair<string,int>> ans;

int kind(char ch)
{
    if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return 1;
    if (ch>='0'&&ch<='9') return 2;
    if (ch=='-'||ch=='/'||ch=='('||ch==')'||ch=='='||ch=='<'||ch=='>'||ch=='+'||ch=='*'||ch==','||ch==';'||ch=='{'||ch=='}'||ch=='"') return 3;
    return 0;
}
void init()
{
    keyK["int"]=1,keyK["void"]=2,keyK["break"]=3,keyK["float"]=4,keyK["while"]=5;
    keyK["do"]=6,keyK["struct"]=7,keyK["const"]=8,keyK["case"]=9,keyK["for"]=10;
    keyK["return"]=11,keyK["if"]=12,keyK["default"]=13,keyK["else"]=14;
    keyK["long"]=15,keyK["short"]=16,keyK["double"]=17,keyK["char"]=18;
    keyK["unsigned"]=19,keyK["signed"]=20,keyK["union"]=21,keyK["goto"]=22;
    keyK["switch"]=23,keyK["continue"]=24,keyK["typedef"]=25,keyK["cout"]=26;
    keyK["cin"]=27,keyK["main"]=28,keyK["printf"]=29,keyK["scanf"]=30;

    keyP["-"]=1,keyP["/"]=2,keyP["("]=3,keyP[")"]=4,keyP["=="]=5,keyP["<="]=6;
    keyP["<"]=7,keyP["+"]=8,keyP["*"]=9,keyP[">"]=10,keyP["="]=11,keyP[","]=12;
    keyP[";"]=13,keyP["++"]=14,keyP["{"]=15,keyP["}"]=16,keyP["["]=17,keyP["]"]=18;

}
int main()
{
    init();
    //for (auto i:keyK) cout<<i.first<<" "<<i.second<<"\n";
    //for (auto i:keyP) cout<<i.first<<" "<<i.second<<"\n";
    /*
    ifstream infile;
    infile.open("data2.txt",ios::in);
    if (!infile.is_open())
    {
        printf("Not found file!\n");
        return 0;
    }*/ //这里是文件输入输出,你就在cpp文件位置旁边建一个data2.txt文件就行
    string input;
    while(getline(cin,input))
    {
        for (int i=0;i<(int)input.size();i++)
        {
            string tmp;
            //cout<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";
            if (kind(input[i])==3) {
                //cout<<"i=P"<<i<<" ";
                string tt;
                if (input[i+1]=='='||input[i+1]=='+') {
                    tt+=input[i];
                    tt+=input[i+1];
                    ans.push_back({"P",keyP[tt]});
                    //cout<<"(P "<<keyP[tt]<<")";
                    i++;
                }
                else {
                    tt+=input[i];
                    ans.push_back({"P",keyP[tt]});
                    //cout<<"(P "<<keyP[tt]<<")";
                }
            }
            else if (kind(input[i])==2) {
                //cout<<"i=C"<<i<<" ";
                bool flag=false;
                while (kind(input[i])!=3) {
                    if (kind(input[i])==1) flag=true;
                    tmp+=input[i];

                    i++;
                }
                i--;
                if (keyI.find(tmp)!=keyI.end()) {
                    ans.push_back({"I",keyI[tmp]});
                    //cout<<"(I "<<keyI[tmp]<<")";
                }
                else if (keyC.find(tmp)!=keyC.end()) {
                    ans.push_back({"C",keyC[tmp]});
                    //cout<<"(C "<<keyC[tmp]<<")";
                }
                else {
                    if (flag) {
                        keyI[tmp]=idxI;
                        I.push_back(tmp);
                        ans.push_back({"I",idxI});
                        //cout<<"(I "<<idxI<<")";
                        idxI++;
                    }
                    else {
                        keyC[tmp]=idxC;
                        C.push_back(tmp);
                        ans.push_back({"C",idxC});
                        //cout<<"(C "<<idxC<<")";
                        idxC++;
                    }
                }
            }
            else if (kind(input[i])==1) {
                //cout<<"i=K"<<i<<" ";
                bool Find=false;
                while (kind(input[i])!=3) {
                    tmp+=input[i];
                    if (keyK.find(tmp)!=keyK.end()) {
                        Find=true;
                        ans.push_back({"K",keyK[tmp]});
                        //cout<<"(K "<<keyK[tmp]<<")";
                        break;
                    }
                    i++;
                }
                if (Find) continue;
                i--;
                if (keyK.find(tmp)!=keyK.end()) {
                    ans.push_back({"K",keyK[tmp]});
                    //cout<<"(K "<<keyK[tmp]<<")";
                }
                else if (keyI.find(tmp)!=keyI.end()) {
                    ans.push_back({"I",keyI[tmp]});
                    //cout<<"(I "<<keyI[tmp]<<")";
                }
                else {
                    keyI[tmp]=idxI;
                    I.push_back(tmp);
                    ans.push_back({"I",idxI});
                    //cout<<"(I "<<idxI<<")";
                    idxI++;
                }
            }
            //cout<<"2 "<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";
        }
    }
    cout<<"Token :";
    for (auto i:ans) {
        cout<<"(";
        cout<<i.first<<" ";
        cout<<i.second<<")";
    }
    cout<<"\nI :";
    bool flag=false;
    for (auto i:I) {
        if (!flag) flag=true;
        else cout<<" ";
        cout<<i;
    }
    cout<<"\n";
    cout<<"C :";
    flag=false;
    for (auto i:C) {
        if (!flag) flag=true;
        else cout<<" ";
        cout<<i;
    }
    return 0;
}



2. 扩展题:扫描器类的设计

【问题描述】

熟悉并实现一个简单的扫描器,设计扫描器的自动机;设计翻译、生成Token的算法;编写代码并上机调试运行通过。

扫描器可识别的单词包括:关键字、界符、标识符和常数(常数包括如:123 123.567 0.567 12.34e+23 …);

要求常整数输出按十进制输出(测试数据中只有16进制与10进制整数),浮点数考虑到精度问题按输入格式输出(测试数据只有10进制浮点数)。同时使用科学计数法的数字都是浮点数。为降低难度,样例3给出一种边界情况供大家调试。

在面对诸如"a+++++b"以及"a+++b"这种丧心病狂的输入时,界符匹配按照从左向右贪心匹配最长界符的策略进行匹配。

判断字符常量及字符串常量单词,将字符和字符串常量分别保存进单独的常量表CT、ST。例如’a’、”OK”;同时字符串与字符常量均不考虑转义字符("“和带”"的都不考虑)。

可以识别简单的词法错误主要形式为’sdddd’、1.sdasf等,尚未定义的单词等。

其中关键字表、界符表、标识符表、常整数表、常实数表、字符表、字符串表如下:(表中除关键词与界符表的表都可以接着编号继续扩展)

在这里插入图片描述
【输入形式】一行带空格的输入。其中关于数字,对于整型保证仅需考虑10进制与16进制数据,对于浮点型保证仅需考虑10进制数据。

【输出形式】

相应单词的Token序列;

标识符表,整数表,实数表,字符表,字符串表

如果错误则输出"ERROR"。
样例输入】

样例1输入:
120+10.3*12.3e-1;

样例2输入:
a="xyz";

样例3输入:
int a=12.1; float b=15e2, c=0x15e2;

样例4输入:
int a='label';

【样例输出】

样例1输出:
Token :(C1 1)(P 8)(C2 1)(P 9)(C2 2)(P 13)
I :
C1 :120
C2 :10.3 12.3e-1
CT :
ST :

样例2输出:
Token :(I 1)(P 11)(ST 1)(P 13)
I :a
C1 :
C2 :
CT :
ST :xyz

样例3输出:
Token :(K 1)(I 1)(P 11)(C2 1)(P 13)(K 4)(I 2)(P 11)(C2 2)(P 12)(I 3)(P 11)(C1 1)(P 13)
I :a b c 
C1 :5602 
C2 :12.1 15e2 
CT :
ST :

样例4输出:
ERROR

自己写的代码,有个测试点老过不去。

#include<iostream>
#include<unordered_map>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<fstream>
#include<map>
#include<algorithm>
using namespace std;
unordered_map<string, int> keyK;//这个无序是胡乱排序,也不按照自己输入的顺序,后来知道了懒得改了,直接套个vector输出吧
unordered_map<string, int> keyP;
unordered_map<string, int> keyI;
unordered_map<string, int> keyC1;
unordered_map<string, int> keyC2;
unordered_map<string, int> keyCT;
unordered_map<string, int> keyST;
vector<string> I;
vector<string> C1;
vector<string> C2;
vector<string> CT;
vector<string> ST;
map<char, int> shiliu;
vector<pair<string, int> > ans;

int idxI = 1, idxC1 = 1, idxC2 = 1, idxCT = 1, idxST = 1;

bool allFlag;//判断是否ERROR

int kind(char ch)
{
    if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) return 1;
    if (ch >= '0' && ch <= '9') return 2;
    if (ch == '-' || ch == '/' || ch == '(' || ch == ')' || ch == '=' || ch == '<' || ch == '>' || ch == '+' || ch == '*' || ch == ',' || ch == ';' || ch == '{' || ch == '}' || ch == '"') return 3;
    return 0;
}
void init()
{
    shiliu['A'] = 10, shiliu['a'] = 10, shiliu['B'] = 11, shiliu['b'] = 11;
    shiliu['C'] = 12, shiliu['c'] = 12, shiliu['D'] = 13, shiliu['d'] = 13;
    shiliu['E'] = 14, shiliu['e'] = 14, shiliu['F'] = 15, shiliu['f'] = 15;

    keyK["int"] = 1, keyK["void"] = 2, keyK["break"] = 3, keyK["float"] = 4, keyK["while"] = 5;
    keyK["do"] = 6, keyK["struct"] = 7, keyK["const"] = 8, keyK["case"] = 9, keyK["for"] = 10;
    keyK["return"] = 11, keyK["if"] = 12, keyK["default"] = 13, keyK["else"] = 14;
    keyK["long"] = 15, keyK["short"] = 16, keyK["double"] = 17, keyK["char"] = 18;
    keyK["unsigned"] = 19, keyK["signed"] = 20, keyK["union"] = 21, keyK["goto"] = 22;
    keyK["switch"] = 23, keyK["continue"] = 24, keyK["typedef"] = 25, keyK["cout"] = 26;
    keyK["cin"] = 27, keyK["main"] = 28, keyK["printf"] = 29, keyK["scanf"] = 30;

    keyP["-"] = 1, keyP["/"] = 2, keyP["("] = 3, keyP[")"] = 4, keyP["=="] = 5, keyP["<="] = 6;
    keyP["<"] = 7, keyP["+"] = 8, keyP["*"] = 9, keyP[">"] = 10, keyP["="] = 11, keyP[","] = 12;
    keyP[";"] = 13, keyP["++"] = 14, keyP["{"] = 15, keyP["}"] = 16, keyP["["] = 17, keyP["]"] = 18;

}
int main()
{
    init();
    //for (auto i:keyK) cout<<i.first<<" "<<i.second<<"\n";
    //for (auto i:keyP) cout<<i.first<<" "<<i.second<<"\n";
    /*
    ifstream infile;
    infile.open("data2.txt",ios::in);
    if (!infile.is_open())
    {
        printf("Not found file!\n");
        return 0;
    }*/ //这里是文件输入输出,你就在cpp文件位置旁边建一个data2.txt文件就行

    string input;
    while (getline(cin, input))
    {
        for (int i = 0; i < (int)input.size(); i++)
        {
            //if (input[i]==' ') continue;
            string tmp;
            //cout<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";
            if (input[i] == '\'') {
                string tt;
                i++;
                while (input[i] != '\'') {
                    tt += input[i];
                    i++;
                    if (i >= input.size()) {
                        allFlag = true;
                        break;
                    }
                }
                if (tt.size() > 1) allFlag = true;
                if (keyCT.find(tt) != keyCT.end()) {
                    ans.push_back({ "CT",keyCT[tt] });
                }
                else {
                    keyCT[tt] = idxCT;
                    CT.push_back(tt);
                    ans.push_back({ "CT",keyCT[tt] });
                    idxCT++;
                }
            }
            else if (input[i] == '"') {
                string tt;
                i++;
                while (input[i] != '"') {
                    tt += input[i];
                    i++;
                    if (i >= input.size()) {
                        allFlag = true;
                        break;
                    }
                }
                if (keyST.find(tt) != keyST.end()) {
                    ans.push_back({ "ST",keyST[tt] });
                }
                else {
                    keyST[tt] = idxST;
                    ST.push_back(tt);
                    ans.push_back({ "ST",keyST[tt] });
                    idxST++;
                }
            }
            else if (kind(input[i]) == 3) {
                //cout<<"i=P"<<i<<" ";
                string tt;
                if (input[i + 1] == '=' || input[i + 1] == '+') {
                    tt += input[i];
                    tt += input[i + 1];
                    ans.push_back({ "P",keyP[tt] });
                    //cout<<"(P "<<keyP[tt]<<")";
                    i++;
                }
                else {
                    tt += input[i];
                    ans.push_back({ "P",keyP[tt] });
                    //cout<<"(P "<<keyP[tt]<<")";
                }
            }
            else if (kind(input[i]) == 2) {
                bool sixteen = false;
                for (int j = i; kind(input[j]) != 3; j++) {
                    if (input[j] == '0' && input[j + 1] == 'x') {
                        sixteen = true;
                        break;
                    }
                }
                if (sixteen) {
                    i += 2;
                    int res = 0;
                    int cifang = 3;

                    while (kind(input[i]) != 3) {
                        int t1 = 1;
                        for (int j = 0; j < cifang; j++)
                        {
                            t1 *= 16;
                        }
                        if (kind(input[i]) == 1) {
                            res += t1 * shiliu[input[i]];
                        }
                        else {
                            res += t1 * (input[i] - '0');
                        }
                        cifang--;
                        i++;
                    }
                    i--;
                    string tt;
                    while (res) {
                        tt += (res % 10) + '0';
                        res /= 10;
                    }
                    reverse(tt.begin(), tt.end());
                    if (keyC1.find(tt) != keyC1.end()) {
                        ans.push_back({ "C1",keyC1[tt] });
                    }
                    else {
                        keyC1[tt] = idxC1;
                        C1.push_back(tt);
                        ans.push_back({ "C1",keyC1[tt] });
                        idxC1++;
                    }
                    continue;
                }
                bool op = false;
                for (int j = i; kind(input[j]) != 3; j++) {
                    if (input[j] == '.' || input[j] == 'e') {
                        op = true;
                        break;
                    }
                }
                if (op) {//如果带有.或者e的就是常实数或者带e的
                    string tt;
                    bool flag1 = false, flag2 = false;
                    while (kind(input[i]) != 3) {
                        if (input[i] == '.') {
                            if (flag1) {
                                allFlag = true;
                            }
                            flag1 = true;
                        }
                        else if (input[i] == 'e') {
                            if (flag2) {
                                allFlag = true;
                            }
                            //tt+=input[i];
                            //i++;
                            flag2 = true;
                        }
                        else if (kind(input[i]) == 1) {
                            allFlag = true;
                        }
                        else if (input[i] == ' ') allFlag = true;
                        tt += input[i];
                        i++;
                        if (i >= input.size()) break;
                    }
                    i--;
                    if (keyC2.find(tt) != keyC2.end()) {
                        ans.push_back({ "C2",keyC2[tt] });
                    }
                    else {
                        keyC2[tt] = idxC2;
                        C2.push_back(tt);
                        ans.push_back({ "C2",keyC2[tt] });
                        idxC2++;
                    }
                }
                else {
                    bool flag = false;
                    while (kind(input[i]) != 3) {
                        if (kind(input[i]) == 1) flag = true;
                        tmp += input[i];
                        i++;
                        if (i >= input.size()) break;
                    }
                    i--;
                    if (keyI.find(tmp) != keyI.end()) {
                        ans.push_back({ "I",keyI[tmp] });
                        //cout<<"(I "<<keyI[tmp]<<")";
                    }
                    else if (keyC1.find(tmp) != keyC1.end()) {
                        ans.push_back({ "C1",keyC1[tmp] });
                        //cout<<"(C "<<keyC1[tmp]<<")";
                    }
                    else {
                        if (flag) {
                            keyI[tmp] = idxI;
                            I.push_back(tmp);
                            ans.push_back({ "I",idxI });
                            //cout<<"(I "<<idxI<<")";
                            idxI++;
                        }
                        else {
                            keyC1[tmp] = idxC1;
                            C1.push_back(tmp);
                            ans.push_back({ "C1",idxC1 });
                            //cout<<"(C "<<idxC1<<")";
                            idxC1++;
                        }
                    }
                }
            }
            else if (kind(input[i]) == 1) {
                //cout<<"i=K"<<i<<" ";
                bool Find = false;
                while (kind(input[i]) != 3) {
                    tmp += input[i];
                    if (keyK.find(tmp) != keyK.end()) {
                        Find = true;
                        ans.push_back({ "K",keyK[tmp] });
                        //cout<<"(K "<<keyK[tmp]<<")";
                        break;
                    }
                    i++;
                    if (i >= input.size()) break;
                }
                if (Find) continue;
                i--;
                if (keyK.find(tmp) != keyK.end()) {
                    ans.push_back({ "K",keyK[tmp] });
                    //cout<<"(K "<<keyK[tmp]<<")";
                }
                else if (keyI.find(tmp) != keyI.end()) {
                    ans.push_back({ "I",keyI[tmp] });
                    //cout<<"(I "<<keyI[tmp]<<")";
                }
                else {
                    keyI[tmp] = idxI;
                    I.push_back(tmp);
                    ans.push_back({ "I",idxI });
                    //cout<<"(I "<<idxI<<")";
                    idxI++;
                }
            }
            //cout<<"2 "<<i<<" "<<input[i]<<" "<<kind(input[i])<<"\n";
        }
    }
    if (allFlag) {
        cout << "ERROR";
        return 0;
    }
    cout << "Token :";
    for (auto i : ans)
    {
        cout << "(";
        cout << i.first << " ";
        cout << i.second << ")";
    }
    cout << "\nI :";
    bool flag = false;
    for (auto i : I) {
        if (!flag) flag = true;
        else cout << " ";
        cout << i;
    }
    cout << "\n";
    cout << "C1 :";
    flag = false;
    for (auto i : C1) {
        if (!flag) flag = true;
        else cout << " ";
        cout << i;
    }
    cout << "\nC2 :";
    flag = false;
    for (auto i : C2) {
        if (!flag) flag = true;
        else cout << " ";
        cout << i;
    }
    cout << "\nCT :";
    flag = false;
    for (auto i : CT) {
        if (!flag) flag = true;
        else cout << " ";
        cout << i;
    }
    cout << "\nST :";
    flag = false;
    for (auto i : ST) {
        if (!flag) flag = true;
        else cout << " ";
        cout << i;
    }
    return 0;
}


好哥们的代码,这个能过能验收

#include<bits/stdc++.h>
using namespace std;
string K[20]={"int","void","break","float","while","do","struct","const","case","for","return","if","default","else"};
string P[25]={"-","/","(",")","==","<=","<","+","*",">","=",",",";","++","{","}"};
vector<string> I,C2,ST;
vector<char> CT;
vector<int> C;
string s,ans;
int m[256];
bool yzf(char c)
{
	return (c>='a'&&c<='z')||(c>='A'&&c<='Z');
}
bool yc(char c)
{
	return c>='0'&&c<='9';
}
bool yc16(char c)
{
	return (c>='0'&&c<='9')||(c>='a'&&c<='f')||(c>='A'&&c<='F');
}
string itos(int x)
{
	string c;
	stack<int> sta;
	while(x){sta.push(x%10);x/=10;}
	while(!sta.empty()){c.push_back(sta.top()+'0');sta.pop();}
	return c;
}
int getC2(string& s,int x,string& c)
{
	int i;
	for(i=x+c.size();i<s.size();i++)
		if(yc(s[i]))c+=s[i];
		else break;
	if(i<s.size()&&s[i]=='e')
	{
		c+=s[i];
		for(i++;i<s.size();i++)
			if(yc(s[i])||s[i]=='-')c+=s[i];
			else break;
	}
	for(i=0;i<C2.size();i++)
		if(C2[i]==c){ans+="(C2 ";ans+=itos(i+1);ans+=")";return x+c.size();}
	C2.push_back(c);ans+="(C2 ";ans+=itos(C2.size());ans+=")";
	return x+c.size();
}
int getC(string& s,int x)
{
	int i,c=0,base;
	string c2;
	if(s[x]=='0'&&(s.size()>x+1&&s[x+1]=='x'))base=16,x+=2;
	else base=10;
	for(i=x;i<s.size();i++)
		if((base==10&&yc(s[i]))||(base==16&&yc16(s[i])))c=c*base+m[s[i]],c2+=s[i];
		else if(s[i]=='.'||s[i]=='e')
		{
			if(i+1<s.size()&&!yc(s[i+1]))return -1;
			c2+=s[i];return getC2(s,x,c2);
		}
		else break;
	for(i=0;i<C.size();i++)
		if(C[i]==c){ans+="(C1 ";ans+=itos(i+1);ans+=")";return x+c2.size();}
	C.push_back(c);ans+="(C1 ";ans+=itos(C.size());ans+=")";
	return x+c2.size();
}
int getI(string& s,int x)
{
	int i;
	string c;
	for(i=x;i<s.size();i++)
		if(s[i]=='_'||yzf(s[i])||yc(s[i]))c+=s[i];
		else break;
	for(i=0;i<I.size();i++)
		if(I[i]==c){ans+="(I ";ans+=itos(i+1);ans+=")";;return x+c.size();}
	I.push_back(c);ans+="(I ";ans+=itos(I.size());ans+=")";
	return x+c.size();
}
int getKI(string& s,int x)
{
	int i;
	string c;
	for(i=x;i<s.size();i++)
		if(yzf(s[i]))c+=s[i];
		else break;
	for(i=0;K[i].size();i++)
		if(K[i]==c){ans+="(K ";ans+=itos(i+1);ans+=")";return x+c.size();}
	return getI(s,x);
}
int getP(string& s,int x)
{
	int i;
	string c;c+=s[x];
	if(x+1<s.size())c+=s[x+1];
	for(i=0;P[i].size();i++)
		if(P[i]==c){ans+="(P ";ans+=itos(i+1);ans+=")";return x+c.size();}
	c.clear();c+=s[x];
	for(i=0;P[i].size();i++)
		if(P[i]==c){ans+="(P ";ans+=itos(i+1);ans+=")";return x+c.size();}
}
int getST(string& s,int x)
{
	int i;
	string c;
	for(i=x;i<s.size();i++)
		if(s[i]!='"')c+=s[i];
		else break;
	for(i=0;i<ST.size();i++)
		if(ST[i]==c){ans+="(ST ",ans+=itos(i+1),ans+=")";return x+c.size()+1;}
	ST.push_back(c);ans+="(ST ",ans+=itos(ST.size()),ans+=")";
	return x+c.size()+1;
}
int getCT(string& s,int x)
{
	int i;
	char c=s[x];
	if(s.size()>x+1&&s[x+1]!='\'')return -1;
	for(i=0;i<CT.size();i++)
		if(CT[i]==c){ans+="(CT ",ans+=itos(i+1),ans+=")";return x+2;}
	CT.push_back(c);ans+="(CT ",ans+=itos(CT.size()),ans+=")";
	return x+2;
}
bool solveToken(string& s)
{
	int i;
	string c;
	ans+="Token :";
	for(i=0;i<s.size()&&i>=0;)
	{
		if(s[i]>='0'&&s[i]<='9')i=getC(s,i);
		else if(s[i]=='_')i=getI(s,i);
		else if(yzf(s[i]))i=getKI(s,i);
		else if(s[i]=='"')i=getST(s,i+1);
		else if(s[i]=='\'')i=getCT(s,i+1);
		else if(s[i]==' ')i++;
		else i=getP(s,i);
	}
	if(i<0){cout<<"ERROR";return false;}
	else {cout<<ans;return true;}
}
int main()
{
	int i,j;
	for(i='0';i<='9';i++)m[i]=i-'0';
	for(i='a';i<='f';i++)m[i-'a'+'A']=m[i]=i-'a'+10;
	getline(cin,s);
	if(!solveToken(s))return 0;
	cout<<"\nI :";
	for(i=0;i<I.size();i++)
	{
		cout<<I[i];if(i!=I.size()-1)cout<<' ';
	}
	cout<<"\nC1 :";
	for(i=0;i<C.size();i++)
	{
		cout<<C[i];if(i!=C.size()-1)cout<<' ';
	}
	cout<<"\nC2 :";
	for(i=0;i<C2.size();i++)
	{
		cout<<C2[i];if(i!=C2.size()-1)cout<<' ';
	}
	cout<<"\nCT :";
	for(i=0;i<CT.size();i++)
	{
		cout<<CT[i];if(i!=CT.size()-1)cout<<' ';
	}
	cout<<"\nST :";
	for(i=0;i<ST.size();i++)
	{
		cout<<ST[i];if(i!=ST.size()-1)cout<<' ';
	}
	return 0;
}

  • 19
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值