@zzzc18
2019-12-18T19:51:51.000000Z
字数 3448
阅读 905
C++
#define ZZZC18
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
enum TokenConst {
END_DOCUMENT = 0, // JSON文档结束
BEGIN_OBJECT, //开始一个JSON object {
END_OBJECT, //结束一个JSON object }
BEGIN_ARRAY, //开始一个JSON array [
END_ARRAY, //结束一个JSON array ]
COLON, //读取一个冒号
COMMA, //读取一个逗号
STRING, //一个String
BOOLEAN, //一个true或false
NUMBER, //一个number
_NULL //一个null
};
class BUF {
public:
static const int MAXLEN = 30000;
char str[MAXLEN];
int len;
int ptr;
void init();
char nextChar();
char peekChar();
string nextString(int);
bool checkEOF();
} file;
class Token {
public:
vector<string> data;
vector<string>::iterator I;
void init(BUF*);
TokenConst readToken();
void displayToken(); // Debug purpose
} token;
double convertS2N(string& src) {
double ret = 0, tmp;
int sign = 1;
int pos = 0;
// sign
if (src[0] == '-') {
sign = -1;
pos = 1;
}
// before dot
tmp = 0;
for (; pos < src.length(); pos++) {
if (src[pos] < '0' || src[pos] > '9') break;
tmp *= 10;
tmp += src[pos] ^ '0';
}
ret += tmp;
if (pos == src.length()) return ret * sign;
// has dot
tmp = 0;
if (src[pos] == '.') {
for (pos++; pos < src.length(); pos++) {
if (src[pos] < '0' || src[pos] > '9') break;
tmp *= 10;
tmp += src[pos] ^ '0';
}
}
while (tmp > 1) tmp /= 10;
ret += tmp;
if (pos == src.length()) return ret * sign;
// has Exp
tmp = 0;
if (src[pos] == 'e' || src[pos] == 'E') {
int e_sign = 1;
if (src[++pos] == '-') {
e_sign = -1;
pos++;
}
for (; pos < src.length(); pos++) {
if (src[pos] < '0' || src[pos] > '9') break;
tmp *= 10;
tmp += src[pos] ^ '0';
}
tmp *= e_sign;
ret *= pow(10, tmp);
}
return ret * sign;
}
int main() {
#ifdef ZZZC18
freopen(".\\testdata\\C.json", "r", stdin);
freopen("out.out", "w", stdout);
#endif
file.init();
token.init(&file);
token.displayToken();
for (int i = 0; i < token.data.size(); i++) {
cerr << token.readToken() << endl;
token.I++;
}
return 0;
}
void BUF::init() {
char ch;
len = ptr = 0;
while (scanf("%c", &ch) != EOF) {
str[len++] = ch;
}
}
char BUF::nextChar() { return str[ptr++]; }
char BUF::peekChar() { return str[ptr]; }
string BUF::nextString(int length) {
static string ret;
ret.clear();
for (int i = 0; i < length; i++, ptr++) {
ret.push_back(str[ptr]);
}
return ret;
}
bool BUF::checkEOF() { return ptr == len; }
void Token::init(BUF* now) {
static string tmp;
while (!now->checkEOF()) {
tmp.clear();
char ch = now->nextChar();
if (ch == '{') tmp.push_back('{');
if (ch == '}') tmp.push_back('}');
if (ch == '[') tmp.push_back('[');
if (ch == ']') tmp.push_back(']');
// bracket
if (ch == ',') tmp.push_back(',');
// comma
if (ch == ':') tmp.push_back(':');
// colone
if (ch == '\"') { // string
tmp.push_back(ch);
while (true) {
ch = now->peekChar();
if (ch == '\\') {
tmp.push_back(now->nextChar()); // character:'\'
tmp.push_back(now->nextChar()); // character after '\'
ch = now->peekChar();
}
if (ch == '\"') {
tmp.push_back(now->nextChar());
break;
}
tmp.push_back(now->nextChar());
}
}
if ((ch >= '0' && ch <= '9') || ch == '-') { // number
tmp.push_back(ch);
while (true) {
ch = now->peekChar();
if ((ch >= '0' && ch <= '9') || ch == '.' || ch == 'e' ||
ch == 'E' || ch == '+' || ch == '-')
tmp.push_back(now->nextChar());
else
break;
}
}
if (ch == 'n') { // null
tmp.push_back(ch);
// cerr << now->nextString(3) << endl;
tmp += now->nextString(3);
}
if (ch == 't') { // true
tmp.push_back(ch);
tmp += now->nextString(3);
}
if (ch == 'f') { // false
tmp.push_back(ch);
tmp += now->nextString(4);
}
if (!tmp.empty()) data.push_back(tmp);
}
// initialize iterator
I = data.begin();
}
void Token::displayToken() {
for (int i = 0; i < data.size(); i++) {
cout << data[i] << endl;
}
}
TokenConst Token::readToken() {
static string now = *I;
if (now[0] == '{') return BEGIN_OBJECT;
if (now[0] == '}') return END_OBJECT;
if (now[0] == '[') return BEGIN_ARRAY;
if (now[0] == ']') return END_ARRAY;
if (now[0] == ':') return COLON;
if (now[0] == ',') return COMMA;
if (now[0] == '\"') return STRING;
if (now[0] == 'n') return _NULL;
if (now[0] == 't' || now[0] == 'f') return BOOLEAN;
return NUMBER;
}