#include<iostream>
#include<math.h>
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<string.h>
using namespace std;
#define MAXLABLESIZE 20
#define INCREMENT 5
typedef class token {//token
public:
token(string lableName, string i) {
data = data + '(' + lableName + " " + i + ')';
next = NULL;
}
string data;
class token* next;
}token, * List;
typedef class tokenList {
public:
tokenList() {
tokenNumber = 0;
head = tail = NULL;
}
class token* head;
class token* tail;
void value(string lableName, string str);
void traverse();
int tokenNumber;
}tokenList;
typedef class alterableLabel {
public:
alterableLabel(string n);
~alterableLabel() {}
protected:
string name;
int number;
int capacity;
}alterableLabel;
string* K = new string[15]{ "\0","int","void","break","float","while","do","struct","const","case","for","return","if","default","else" };
string* P = new string[17]{ "\0","-","/","(",")","==","<=","<","+","*",">","=",",",";","++","{","}" };
int a[13] = { 1,2,3,4,7,8,9,10,11,12,13,15,16 };
int b[3] = { 5,6,14 };
class I : public alterableLabel {
public:
I(string n);
void addNode(string newNode);
bool inLable(string node);
int getNodeNumber(string Node);
int getNumber() {
return number;
}
void traverse();
~I() {}
private:
string* p;
};
class CT : public alterableLabel {
CT(string n);
void addNode(char newNode);
int getNumber() {
return number;
}
bool inLable(char node);
int getNodeNumber(char Node);
void traverse();
~CT() {}
private:
char* p;
};
alterableLabel::alterableLabel(string n) {
this->name = n;
this->number = 0;
this->capacity = MAXLABLESIZE;
}
I::I(string n) :alterableLabel(n) {
name = n;
this->number = 0;
this->capacity = MAXLABLESIZE;
this->p = new string[capacity]();
}
void I::addNode(string newNode) {
if (number >= capacity - 1) {
string* r = new string[capacity + INCREMENT]();
copy(p, p + capacity, r);
delete[] p;//将原来的内存单元释放
p = r;
capacity = capacity + INCREMENT;
p[++number] = newNode;
}
else {
p[++number] = newNode;
}
}
bool I::inLable(string node) {
for (int i = 1; i <= this->number; i++) {
if (node == p[i]) {
return true;
}
}
return false;
}
int I::getNodeNumber(string node) {
for (int i = 1; i <= this->number; i++) {
if (node == p[i]) {
return i;//返回位置
}
}
cout << "ERROR" << endl;
return-1;
}
void I::traverse() {
cout << this->name << " :";
int i = 1;
for (i = 1; i < this->number; i++) {
cout << p[i] << ' ';
}
cout << p[i];
}
CT::CT(string n) :alterableLabel(n) {
name = n;
this->number = 0;
this->capacity = MAXLABLESIZE;
this->p = new char[capacity]();
}
void CT::addNode(char newNode) {
if (number >= capacity - 1) {
char* q = new char[capacity + INCREMENT]();
memcpy(q, p, capacity);
capacity = capacity + INCREMENT;
delete[]p;
p = q;
p[++number] = newNode;
}
else {
p[++number] = newNode;
}
}
bool CT::inLable(char node) {
for (int i = 1; i <= this->number; i++) {
if (node == p[i]) {
return true;
}
}
return false;
}
void CT::traverse() {
cout << this->name << ' ' << ':';
for (int i = 1; i < this->number; i++) {
cout << p[i] << ' ';
}
cout << p[number] << endl;
}
int CT::getNodeNumber(char node) {
for (int i = 1; i <= this->number; i++) {
if (node == p[i]) {
return i;//返回位置
}
}
cout << "ERROR" << endl;
return -1;
}
bool isChar(char a) {
if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z')) {
return true;
}
else {
return false;
}
}
bool isNumber(char n) {
if ((n - '0') >= 0 && (n - '0') <= 9) {
return true;
}
else {
return false;
}
}
void tokenList::value(string lableName, string str) {
List p = new token(lableName, str);
if (head == NULL) {//
head = tail = p;
this->tokenNumber++;
}
else {
tail->next = p;
tail = p;
this->tokenNumber++;
}
}
void tokenList::traverse() {
List p = this->head;
if (p == NULL) {
cout << "ERROR" << endl;
return;
}
else {
while (p != NULL) {
cout << p->data;
p = p->next;
}
}
}
void scanString(tokenList& list, I& ii, I& c1) {
string str;
getline(cin, str);
string temp;
for (int i = 0; i < int(str.size()); i++) {
if ((int(str.size()) - i) >= 1 && isNumber(str.at(i))) {//如果当前至少还有一个字符,并且这个字符是数字
temp = temp + str.at(i);//当前数字存入temp
int flag = i;//记住当前数字的位置
if (int(str.size()) - i >= 2) {//如果下一个位置仍然有字符
i++;//指针移动到下一个字符
while (isNumber(str.at(i))) {//i指向的字符始终为数字就继续循环
temp = temp + str.at(i);
i++;
}
if (i < int(str.size()) && (str.at(i) == '.' || str.at(i) == 'e')) {//如果至少有一个字符,并且下一个字符是./e代表不是整常数
i = flag;//回退起始位置,让下面的小数判断程序来读
temp.clear();
}
else {
if ((int(str.size()) - i >= 2) && str[i - 1] == '0' && str.at(i) == 'x') {//判断当前字符是否为x
temp.erase(temp.end() - 1);//将末尾的零剔除
if (!c1.inLable(temp)) {
c1.addNode(temp);
list.value("C", to_string(c1.getNumber()));
}
else {
list.value("C", to_string(c1.getNodeNumber(temp)));
}
temp.clear();
i = i - 2;
continue;
/* int j = 0;
int number = 0;
while (isNumber(str.at(i)) || (str.at(i) >= 'a' && str.at(i) <= 'f')) {
temp = temp + str.at(i);
i++;
j++;
}
for (int k = j - 1; k >= 0; k--) {
if (isNumber(temp.at(k))) {
number = number + (temp.at(k) - '0') * int(pow(16, j - 1 - k));
}
else {
number = number + (temp.at(k) - 87) * int(pow(16, j - 1 - k));
}
}
temp.clear();
temp = temp + to_string(number);
if (!c1.inLable(temp)) {
c1.addNode(temp);
}
list.value("C1", to_string(c1.getNumber()));
temp.clear();
continue;*/
}
else {
if (!c1.inLable(temp)) {
c1.addNode(temp);
list.value("C", to_string(c1.getNumber()));
}
else {
list.value("C", to_string(c1.getNodeNumber(temp)));
}
i--;
temp.clear();
continue;
}
if (!c1.inLable(temp)) {
c1.addNode(temp);
}
list.value("C", to_string(c1.getNumber()));
temp.clear();
continue;
}
}
else {//仅有当前一个整数
if (!c1.inLable(temp)) {
c1.addNode(temp);
list.value("C", to_string(c1.getNumber()));
}
else {
list.value("C", to_string(c1.getNodeNumber(temp)));
}
continue;
}
}
if ((int(str.size()) - i) >= 1 && (isChar(str.at(i)) || str.at(i) == '_')) {//当前至少有一个字符,并且以字母或下划线开头
temp = temp + str.at(i);
i++;
while (i < int(str.size()) && (isChar(str.at(i)) || isNumber(str.at(i)) || str.at(i) == '_')) {
temp = temp + str.at(i);
i++;
}
int j = 0;
for (j = 1; j <= 14; j++) {//看是否这些字符属于关键字
if (temp == K[j]) {
list.value("K", to_string(j));//属于关键字
i--;
break;
}
}
if (temp == K[j]) {//属于关键字进行下一次单词检查
temp.clear();
continue;
}
if (!ii.inLable(temp)) {
ii.addNode(temp);
list.value("I", to_string(ii.getNumber()));
}
else {
list.value("I", to_string(ii.getNodeNumber(temp)));
}
temp.clear();
i--;
continue;
}
if ((int(str.size()) - i) >= 1) {
if (int(str.size() - i) >= 2) {//此时有接下来两个字符是双界符的机会
temp = temp + str.at(i);
temp = temp + str.at(i + 1);
int j = 0;
for (j = 0; j < 3; j++) {
if (temp == P[b[j]]) {//证明这两个字符是双界符
list.value("P", to_string(b[j]));
i++;
break;
}
}
if (temp == P[b[j]]) {
temp.clear();
continue;
}
}
temp.clear();
temp = temp + str.at(i);
int j = 0;
for (j = 0; j < 13; j++) {
if (temp == P[a[j]]) {
list.value("P", to_string(a[j]));
break;
}
}
if (temp == P[a[j]]) {
temp.clear();
continue;
}
temp.clear();
continue;
}
if (str.at(i) == ' ') {
continue;
}
}
}
int main() {
I i("I");
I c1("C");
//I c2("C2");
//CT ct("CT");
//I st("ST");
tokenList l;
scanString(l, i, c1);
cout << "Token :";
l.traverse();
cout << endl;
i.traverse();
cout << endl;
c1.traverse();
//cout << endl;
/*c2.traverse();
cout << endl;
ct.traverse();
cout << endl;
st.traverse();
*/
}