本人没咋学编译原理,能力有限,写的不好轻点喷,大佬路过的话,那你就路过就好
东大编译原理实验课原题,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;
}