勿抄,请不要限制你的想象力。
改进之处:遇到不能识别的应该继续往后识别,功能未完善。
思路:看代码就懂了;
Talk is cheap. Show me the code.
#include <bits/stdc++.h>//万用头文件
using namespace std;
//——————————全局变量——————————
struct Keyword
{
string token;
int syn;
}Key[13];
int syn,tag=1;//种别码,标记
string token;
int i = 0;//全局变量作为下标
//————————————————————————————
bool judletter(char ch)//判断字符
{
if (ch>='A'&& ch<='Z'|| ch >= 'a'&& ch <= 'z')
return 1;
else
return 0;
}
bool judnum(char num)//判断数字
{
if (num>='0'&&num<='9')
return 1;
else
return 0;
}
int scan(string input)//对单个字符块进行扫描
{
if (input[i]==' ')//空格
{
syn = -2;
i++;
return syn;
}
token = "";//NULL默认为0,不为空
if (judnum(input[i]))//数字开头
{
int sum = 0;
while (judnum(input[i]))
{
sum = 10 * sum + (input[i] - '0');
i++;
syn = 20;
}
token += to_string(sum);
return syn;
}
if (judletter(input[i]))//字母开头可能为1、标识符 2、关键字
{
while (judletter(input[i])||judnum( input[i]))
{
token += input[i];
i++;
}
syn = 10;//标识符(e.g.变量、常量)
for (int j = 1; j <= 12; j++)//
{
if (token == Key[j].token)
{
syn = Key[j].syn;
return syn;
}
}
return syn;
}
else //符号
{
token = "";
switch (input[i]) {
case'=':
syn = 21;
i++;
token = "=";
if (input[i]=='=')
{
syn = 39;
i++;
token = "==";
}
return syn;
break;//多余,习惯case+break
case '+':
syn = 22;
i++;
token = "+";
return syn;
case'-':
syn = 23;
i++;
token = "-";
return syn;
case'*':
syn = 24;
i++;
token = "*";
return syn;
case'/':
syn = 25;
i++;
token = "/";
return syn;
case'(':
syn = 26;
i++;
token = "(";
return syn;
case')':
syn = 27;
i++;
token = ")";
return syn;
case'[':
syn = 28;
i++;
token = "[";
return syn;
case']':
syn = 29;
i++;
token = "]";
return syn;
case'{':
syn = 30;
i++;
token = "{";
return syn;
case'}':
syn = 31;
i++;
token = "}";
return syn;
case',':
syn = 32;
i++;
token = ",";
return syn;
case':':
syn = 33;
i++;
token = ":";
return syn;
case';':
syn = 34;
i++;
token = ";";
return syn;
case'>':
syn = 35;
i++;
token = ">";
if (input[i] == '=')
{
syn = 37;
i++;
token = ">=";
}
return syn;
case'<':
syn = 36;
i++;
token = "<";
if (input[i] == '=')
{
syn = 38;
i++;
token = "<=";
}
return syn;
case'!':
syn = -1;//若只有一个!则报错
i++;
if (input[i] == '=')
{
syn = 40;
i++;
token = "!=";
}
return syn;
case'"'://此处仍需改进 ,"也应该作为一个单独单词符号,拥有种别码
syn = -1;
token += input[i];
i++;
while (input[i] != '"')
{
if (input[i] == '#')
{
tag = 0;
break;
}
else
{
token += input[i];
i++;
}
}
//————————————
if (tag)
{
token += input[i];
i++;
syn = 50;
return syn;
}
else
{
syn = -3;
return syn;
}
case '#':
syn = 0;
return syn;
break;
default:
syn = -1;
return syn;
break;
}
}
}
void initial()//初始化保留字
{
Key[1] = { "main",1 };
Key[2] = { "int",2 };
Key[3] = { "char",3 };
Key[4] = { "if",4 };
Key[5] = { "else",5 };
Key[6] = { "for",6 };
Key[7] = { "while",7 };
Key[8] = { "return",8 };
Key[9] = { "void",9 };
Key[10] = { "STRING",50 };
Key[11] = { "ID",10 };
Key[12] = { "INT",20 };
}
string input()//读取本地文件,code.txt位于本项目cpp存放地,若更改位置则需输入相应地址,
//注:window的地址和代码地址\两个地址符相反/
{
//把全部文件读取放入string a中
ifstream in("code.txt", ios::in);
istreambuf_iterator<char> beg(in), end;
string a(beg, end);//或者string a;a.assign(beg,end);
in.close();
return a;
}
void output(string a)//输出,循环在此实现
{
cout << "(种别码,token/sum)" << endl;
int syn;
do
{
syn = scan(a);
switch (syn)
{
case -1:
cout << "error 非法字符" << endl;
syn = 0;
break;
case -2:
break;
case -3:
cout << "语法错误(引号不全)" << endl;
syn = 0;
default:
cout << "(" << syn << "," << token << ")" << endl;
}
} while (syn!=0);
}
int main()
{
initial();//初始化
string a = input();//读取文件置入字符串a中,样例把换行读成/n
//cout << "请输入以#结尾的字符串" << endl;
/*若想cmd内输入,则把input()那一行换成下面这些;
string a;
//getline(cin,a);
*/
cout << "读取到的字符串为:" << a << endl;
output(a);
return 0;
}