// We know its an object, so data format is // e -> <tag>d</tag> // d -> <tag>d</tag> | term private static Dictionary <string, dynamic> ParseObject(Span <XMLToken> tokens) { var ret = new Dictionary <string, dynamic>(); for (int i = 0; i < tokens.Length; ++i) { string key = tokens[i].data; ++i; // <tag>term</tag> if (tokens[i].IsData()) { ret[key] = new Common.ASTString(tokens[i].data); // TODO : check if tag is closed ++i; continue; } // token is a opening tag // new object since key and optag arent same if (!tokens[i].IsOpening(key)) { int begin = i; while (i < tokens.Length && !tokens[i].IsClosing(key)) { ++i; } ret[key] = ParseObject(tokens.Slice(begin, i - begin)); continue; } // collection since key and optag are same if (tokens[i].IsOpening(key)) { int begin = i, top = 1; while (i < tokens.Length && top > 0) { if (tokens[i].IsClosing(key)) { --top; } if (tokens[i].IsOpening(key)) { ++top; } ++i; } ret[key] = ParseCollection(tokens.Slice(begin, i - begin - 1)); --i; continue; } throw new NotSupportedException("Invalid XML format."); } return(ret); }
// Parses a JSON object ( starting and ending with '{' and '}' ) public static Dictionary <string, dynamic> ParseJSON(Span <JSONToken> tokens) { int len = tokens.Length; Dictionary <string, dynamic> ret = new Dictionary <string, dynamic>(); for (int i = 1; i < len - 1; ++i) { string key = tokens[i].content; if (!tokens[++i].IsColon()) { throw new NotImplementedException("Invalid JSON expression."); } switch (tokens[++i].type) { case JSONTokenType.STRING: ret[key] = new Common.ASTString(tokens[i].content); if (tokens[i + 1].IsComma()) { ++i; } continue; case JSONTokenType.NUMBER: ret[key] = new Common.ASTNumber(tokens[i].content); if (tokens[i + 1].IsComma()) { ++i; } continue; case JSONTokenType.BOOL: ret[key] = new Common.ASTBoolean(tokens[i].content == "true"); if (tokens[i + 1].IsComma()) { ++i; } continue; case JSONTokenType.SYMBOL: if (tokens[i].content == "{") // Object { int begin = i, stack = 1; ++i; while (stack != 0) { if (tokens[i].IsObjectOpening()) { ++stack; } if (tokens[i].IsObjectClosing()) { --stack; } if (stack == 0) { var sliced = tokens.Slice(begin, i - begin + 1); ret[key] = ParseJSON(sliced); ++i; continue; } ++i; } } else if (tokens[i].content == "[") // Collection { int begin = i, stack = 1; ++i; while (stack != 0) { if (tokens[i].IsCollectionOpening()) { ++stack; } if (tokens[i].IsCollectionClosing()) { --stack; } if (stack == 0) { var sliced = tokens.Slice(begin, i - begin + 1); ret[key] = ParseCollection(sliced); ++i; continue; } ++i; } } continue; } } return(ret); }