C# Library for the Fjord Config Format
at master 5.5 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6 7using static libfcf.Tokenizer; 8 9namespace libfcf; 10 11public static class Parser 12{ 13 internal static dynamic[] ParseDict(Token[] tokens) 14 { 15 Dictionary<string, dynamic> json_object = new Dictionary<string, dynamic>(); 16 var t = tokens[0]; 17 if (t.GetType() == typeof(TokenDictEnd)) 18 { 19 return new dynamic[] { json_object, tokens.ToList().Skip(1).ToArray() }; 20 } 21 22 while (true) 23 { 24 var json_key = tokens[0]; 25 if (json_key.GetType() == typeof(TokenIdentifier)) 26 { 27 tokens = tokens.ToList().Skip(1).ToArray(); 28 } 29 else 30 { 31 throw new InvalidTokenTypeException("Expected identifier type for key got: " + GetTokenAsHuman(json_key), json_key); 32 } 33 34 if (tokens[0].GetType() != typeof(TokenAssign)) 35 { 36 throw new InvalidTokenTypeException($"Expected '=' got {GetTokenAsHuman(tokens[0])}", tokens[0]); 37 } 38 39 var tmp = Parse(tokens.ToList().Skip(1).ToArray()); 40 var json_value = tmp[0]; 41 tokens = tmp[1]; 42 43 if (!(json_value.GetType() == typeof(TokenString) || json_value.GetType() == typeof(TokenNumber) || json_value.GetType() == typeof(TokenBoolean) || 44 json_value.GetType() == typeof(List<dynamic>) || json_value.GetType() == typeof(Dictionary<string, dynamic>))) 45 { 46 throw new InvalidTokenTypeException($"expected string, number or bool got {GetTokenAsHuman(json_value)}", json_value); 47 } 48 49 // json_object.Add((string)(((TokenIdentifier)json_key).value), json_value); 50 51 if (json_value.GetType() == typeof(TokenString) || json_value.GetType() == typeof(TokenNumber) || json_value.GetType() == typeof(TokenBoolean)) 52 { 53 json_object.Add((string)(((TokenIdentifier)json_key).value), ((dynamic)json_value).value); 54 } 55 else 56 { 57 json_object.Add((string)(((TokenIdentifier)json_key).value), json_value); 58 } 59 60 t = tokens[0]; 61 if (t.GetType() == typeof(TokenDictEnd)) 62 { 63 return new dynamic[] { json_object, tokens.ToList().Skip(1).ToArray() }; 64 } 65 else if (t.GetType() != typeof(TokenComma)) 66 { 67 throw new InvalidTokenTypeException($"Expected '=' after pair in object got {GetTokenAsHuman(t)}", t); 68 } 69 70 tokens = tokens.ToList().Skip(1).ToArray(); 71 } 72 } 73 74 internal static dynamic[] ParseArray(Token[] tokens) 75 { 76 List<dynamic> json_array = new List<dynamic>(); 77 78 var t = tokens[0]; 79 if (t.GetType() == typeof(TokenArrayEnd)) 80 { 81 return new dynamic[] { json_array, tokens.ToList().Skip(1).ToArray() }; 82 } 83 84 while (true) 85 { 86 var tmp = Parse(tokens); 87 var json = tmp[0]; 88 tokens = tmp[1]; 89 90 if (json.GetType() == typeof(TokenString) || json.GetType() == typeof(TokenNumber) || json.GetType() == typeof(TokenBoolean) || json.GetType() == typeof(TokenIdentifier)) 91 { 92 json_array.Add(((dynamic)json).value); 93 } 94 else 95 { 96 json_array.Add(json); 97 } 98 99 t = tokens[0]; 100 if (t.GetType() == typeof(TokenArrayEnd)) 101 { 102 return new dynamic[] { json_array, tokens.ToList().Skip(1).ToArray() }; 103 } 104 else if (t.GetType() != typeof(TokenComma)) 105 { 106 throw new InvalidTokenTypeException($"Expected comma after object in array got {GetTokenAsHuman(t)}", t); 107 } 108 else 109 { 110 tokens = tokens.ToList().Skip(1).ToArray(); 111 } 112 } 113 } 114 115 internal static dynamic[] Parse(Token[] tokens) 116 { 117 var t = tokens[0]; 118 119 // Console.WriteLine("Parsing Array"); 120 if (t.GetType() == typeof(TokenArrayStart)) 121 { 122 // Console.WriteLine("Parsing Array: " + t); 123 return ParseArray(tokens.ToList().Skip(1).ToArray()); 124 } 125 else if (t.GetType() == typeof(TokenDictStart)) 126 { 127 // Console.WriteLine("Parsing Dict: " + t); 128 return ParseDict(tokens.ToList().Skip(1).ToArray()); 129 } 130 else 131 { 132 return new dynamic[] { t, tokens.ToList().Skip(1).ToArray() }; 133 } 134 } 135 136 public static Dictionary<string, object> DeserializeObject(Token[] tokens) 137 { 138 return (Dictionary<string, object>)Parse(tokens)[0]; 139 } 140 141 public static Dictionary<string, object> DeserializeObjectFromFile(string filePath) 142 { 143 var stack = TokenizeFromFile(filePath); 144 145 return DeserializeObject(stack); 146 } 147 148 public static List<object> DeserializeArray(Token[] tokens) 149 { 150 return (List<object>)Parse(tokens)[0]; 151 } 152 153 public static List<object> DeserializeArrayFromFile(string filePath) 154 { 155 var stack = TokenizeFromFile(filePath); 156 157 return DeserializeArray(stack); 158 } 159 160 public static List<object> DeserializeArrayFromMemory(string memory) 161 { 162 var stack = TokenizeFromMemory(memory.Split('\n')); 163 return DeserializeArray(stack); 164 } 165}