基于C++简易JSON解析器

翻译自Java原版

 正在开发测试中,先贴上Parser类代码。

class JsonParser {
	private:
		char COLON = ':';
	public:
		JsonParser() {} 

		void* parse() {
			CharsRange trimmedJson = CharsRange::newRange(0, jsonStr.size()).trim();
			return processValue(trimmedJson);
		}

		map processPlainObject(CharsRange range) {
			list properties = processProperties(CharsRange::newRange(range.start + 1, range.end - 1));
			map objectMap;
			list::iterator prop;
			for(prop = properties.begin() ; prop != properties.end() ; prop++) {
				objectMap.insert(pair(prop->name, prop->value));
			}
			return objectMap;
		}

		list processProperties(CharsRange range) {
			list properties;
			int nameStartMark = range.start;
			for (int curPos = range.start; curPos < range.end; curPos++) {
				char ch = jsonStr.at(curPos);
				if (ch == COLON) {
					CharsRange nameToken = CharsRange::newRange(nameStartMark, curPos).trim();
					int readCursor = 0;
					void* value = genValue(range, ++curPos, &readCursor);
					curPos = readCursor + 1;
					nameStartMark = curPos;
					string name = genName(nameToken);
					properties.push_back(Property::of(name, value));
				}
			}
			return properties;
		}

		void* genValue(CharsRange range, int curPos, int *readCursor) {
			CharsRange valueSegment = findNextValue(CharsRange::newRange(curPos, range.end), readCursor);
			return processValue(valueSegment);
		}

		string genName(CharsRange nameToken) {
			bool hasQuote = jsonStr.at(nameToken.start) == '"' || jsonStr.at(nameToken.end) == '"';
			int start = hasQuote ? nameToken.start + 1 : nameToken.start;
			int end = hasQuote ? nameToken.end - 1 : nameToken.end;
			return CharsRange::newRange(start, end).toString();
		}

		list processArray(CharsRange range) {
			return processElements(CharsRange::newRange(range.start + 1, range.end - 1));
		}

		list processElements(CharsRange range) {
			list objList;
			int elementStartMark = range.start;
			for (int i = range.start; i < range.end; i++) {
				int readCursor = 0;
				void * elementValue = genValue(range, elementStartMark, &readCursor);
				objList.push_back(elementValue);
				i = readCursor;
				elementStartMark = i + 1;
			}
			return objList;
		}

		/**
		 * @param chars
		 * @return value segment trimmed.
		 */
		CharsRange findNextValue(CharsRange chars, int *readCursor) {
			CharsRange trimChars = chars.trimLeft();
			if (trimChars.relativeChar(0) == '{') {
				return completeSymbolPair(trimChars, readCursor, "{}");
			} else if (trimChars.relativeChar(0) == '[') {
				return completeSymbolPair(trimChars, readCursor, "[]");
			} else {
				int i;
				for (i = trimChars.start + 1; i < trimChars.end; i++) {
					char ch = jsonStr.at(i);
					if (ch == ',') {
						break;
					}
				}
				readCursor = &i;
				return CharsRange::newRange(trimChars.start, i).trim();
			}
		}

		CharsRange completeSymbolPair(CharsRange trimChars, int *readCursor, string symbolPair) {
			int leftSymbol = symbolPair.at(0);
			int rightSymbol = symbolPair.at(1);
			int symbolsScore = 1;
			int i;
			CharsRange valueSegment(0,0);
			for (i = trimChars.start + 1; i < trimChars.end; i++) {
				char ch = jsonStr.at(i);
				if (ch == leftSymbol) {
					symbolsScore++;
				} else if (ch == rightSymbol) {
					symbolsScore--;
				}
				if (symbolsScore == 0) {
					valueSegment = CharsRange::newRange(trimChars.start, i + 1);
					break;
				}
			}
			for (; i < trimChars.end; i++) {
				char chx = jsonStr.at(i);
				if (chx == ',') {
					break;
				}
			}
			readCursor = &i;
			return valueSegment;
		}

		void* processValue(CharsRange valueSegment) {
			void* value;
			if (valueSegment.relativeChar(0) == '"') {
				string rng = CharsRange::newRange(valueSegment.start + 1, valueSegment.end - 1).toString().data();
				value = &rng;
			} else if (valueSegment.relativeChar(0) == '{') {
				map obj = processPlainObject(valueSegment);
				value = &obj;
			} else if (valueSegment.relativeChar(0) == '[') {
				list objLst = processArray(valueSegment);
				value = &objLst;
			} else if (valueSegment.equalsString("true")) {
				bool ret = true;
				value = &ret;
			} else if (valueSegment.equalsString("false")) {
				bool ret = false;
				value = &ret;
			} else if (valueSegment.equalsString("null")) {
				value = NULL;
			} else {
				int ret = atoi(valueSegment.toString().data());
				value = &ret;
			}
			return value;
		}
};

 

你可能感兴趣的:(造轮子,C++,JSON)