Last active
June 1, 2019 13:54
-
-
Save deiuch/283258b74b1cf40b96a44995ccc3822d to your computer and use it in GitHub Desktop.
Code from SLang project on parser's AST serialization into JSON IR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace SLang.Service | |
{ | |
public class JsonIr | |
{ | |
public const string JSON_NULL_REPRESENTATION = "null"; | |
public static string NL { get; set; } = Environment.NewLine; | |
public static string INDENT { get; set; } = " "; | |
private string type; | |
private string value; | |
private List<JsonIr> children = new List<JsonIr>(); | |
public JsonIr(Type type) : this(type, null) { } | |
public JsonIr(Type type, string value) : this(type.Name, value) { } | |
public JsonIr(string typeName) : this(typeName, null) { } | |
public JsonIr(string typeName, string value) | |
{ | |
this.type = typeName ?? throw new ArgumentNullException(); | |
this.value = value; | |
} | |
public JsonIr SetValue(string value) | |
{ | |
this.value = value; | |
return this; | |
} | |
public JsonIr AppendChild(JsonIr child) | |
{ | |
children.Add(child ?? GetIrNull()); | |
return this; | |
} | |
public virtual string Serialize(bool indentation) | |
{ | |
return String.Format( | |
"{{{0}" + | |
"{1}\"type\":{2},{0}" + | |
"{1}\"value\":{3},{0}" + | |
// "{1}\"num_children\":" + children.Count() + ",{0}" + | |
"{1}\"children\":[" + | |
(children.Count() > 0 ? "{0}{1}{1}{4}{0}{1}" : "") + | |
"]{0}" + | |
"}}", | |
indentation ? NL : "", // 0, newline | |
indentation ? INDENT : "", // 1, tabulation | |
JsonifyString(type), // 2, type string | |
JsonifyString(value), // 3, value string | |
string.Join( // 4, childern array | |
"," + (indentation ? NL + INDENT + INDENT : ""), | |
children.Select( // indent each line twice | |
o => o.Serialize(indentation). | |
Replace(NL, NL + INDENT + INDENT) | |
) | |
) | |
); | |
} | |
private static string JsonifyString(string s) | |
{ | |
if (s == null) | |
return JSON_NULL_REPRESENTATION; | |
//return System.Web.Helpers.Json.Encode(s); | |
return "\"" + string.Concat(s.Select( | |
c => char.IsControl(c) ? | |
string.Format("\\u{0:X4}", (ushort)c) : | |
c == '"' ? | |
"\\\"" : | |
c == '\\' ? | |
"\\\\" : | |
c.ToString() | |
)) + "\""; | |
} | |
public static JsonIr ListToJSON<T>(List<T> entities_list) where T : ENTITY | |
{ | |
if (entities_list == null) | |
throw new ArgumentNullException(); | |
JsonIr irList = new JsonIr(typeof(T).Name + "_LIST"); | |
foreach (ENTITY e in entities_list) | |
irList.AppendChild(e.ToJSON()); | |
return irList; | |
} | |
public static JsonIr GetIrNull() | |
{ | |
return JsonIrNull.Get(); | |
} | |
private class JsonIrNull : JsonIr | |
{ | |
private static JsonIrNull instance; | |
private JsonIrNull() : base(JSON_NULL_REPRESENTATION) { } | |
public static JsonIrNull Get() | |
{ | |
if (instance == null) | |
instance = new JsonIrNull(); | |
return instance; | |
} | |
public override string Serialize(bool indentation) | |
{ | |
return JSON_NULL_REPRESENTATION; | |
} | |
} | |
#region Example | |
public class Token | |
{ | |
public string image { get; private set; } // = "+"; | |
// ...other members, constructors and useful methods... | |
} | |
public abstract class ENTITY | |
{ | |
// ...members, constructors and other useful methods... | |
public virtual JsonIr ToJSON() | |
{ | |
return new JsonIr(GetType()); | |
} | |
public static JsonIr ToJSON(ENTITY e) | |
{ | |
if (e == null) return JsonIr.GetIrNull(); | |
return e.ToJSON(); | |
} | |
} | |
public abstract class TYPE : ENTITY | |
{ | |
// ...members, constructors and other useful methods... | |
} | |
public abstract class EXPRESSION : ENTITY | |
{ | |
public TYPE type { get; protected set; } | |
// ...constructors and other useful methods... | |
public override JsonIr ToJSON() | |
{ | |
return base.ToJSON() | |
.AppendChild(ToJSON(type)); | |
} | |
} | |
public class UNARY : EXPRESSION | |
{ | |
public EXPRESSION primary { get; private set; } | |
public Token unaryOp; // = new Token(); | |
// ...constructors and other useful methods... | |
public override JsonIr ToJSON() | |
{ | |
return base.ToJSON() | |
.SetValue(unaryOp.image) | |
.AppendChild(ToJSON(primary)); | |
} | |
} | |
static void Main(string[] args) | |
{ | |
JsonIr example_object = new UNARY(/* args */).ToJSON(); | |
string result = example_object.Serialize(true); | |
Console.WriteLine(result); | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment