Alpha commit

master
Harald Wolff 2017-11-03 13:13:09 +01:00
parent a9a37de231
commit 659088b90e
14 changed files with 956 additions and 112 deletions

View File

@ -2,6 +2,7 @@
using System.Text;
using System.Collections.Generic;
using sharp.extensions;
using System.Globalization;
namespace sharp.json
{
@ -20,6 +21,8 @@ namespace sharp.json
System.Tuple.Create('t','\t'),
};
static List<char> numberScan = new List<char>(new char[] { '-', '0', '1', '2', '3', '4', '5', '7', '8', '9', '.','E','e' });
char[] buffer;
int position;
@ -37,7 +40,7 @@ namespace sharp.json
}
public string Peek(int len){
return new String(buffer.Segment(position,len));
return new String(buffer.Segment(position,len).Extend(len));
}
@ -49,7 +52,7 @@ namespace sharp.json
}
public char[] Read(int len){
if ((position) < buffer.Length){
char[] r = buffer.Segment(position,len);
char[] r = buffer.Segment(position, len).Extend(len);
position += r.Length;
return r;
}
@ -85,22 +88,43 @@ namespace sharp.json
}
public JSON parseNumber(){
Int64 i64 = parseInt64();
List<char> digits = new List<char>();
if (Peek() == '.'){
Read();
Int64 dec = parseInt64();
int lg10 = (int)Math.Log10(dec);
i64 = i64 * lg10;
if (i64 < 0){
i64 -= dec;
} else {
i64 += dec;
do
{
char n = (char)Peek();
if (!numberScan.Contains(n)){
break;
}
return new JSONNumber(((double)i64) / (double)lg10 );
digits.Add(n);
Read();
} while (true);
string sv = new String(digits.ToArray());
if ((sv.IndexOf(".") > 0)||(sv.IndexOf("E") > 0)||(sv.IndexOf("e") > 0))
{
return new JSONNumber(double.Parse(sv,CultureInfo.InvariantCulture));
} else {
return new JSONNumber(i64);
return new JSONNumber(Int64.Parse(sv));
}
//Int64 i64 = parseInt64();
//if (Peek() == '.'){
// Read();
// Int64 dec = parseInt64();
// int lg10 = (int)Math.Log10(dec);
// i64 = i64 * lg10;
// if (i64 < 0){
// i64 -= dec;
// } else {
// i64 += dec;
// }
// return new JSONNumber(((double)i64) / (double)lg10 );
//} else {
// return new JSONNumber(i64);
//}
}
public JSON parseObject(){
@ -138,7 +162,7 @@ namespace sharp.json
scanWhitespace();
continue;
}
throw new FormatException("parser error: expected ',' or '}' but got '{0}'");
throw new FormatException("parser error: expected ',' or '}' but got '"+n+"'");
}
}
return o;
@ -185,20 +209,10 @@ namespace sharp.json
while (Peek() != '"'){
char ch = Read();
if (ch == '\\'){
sb.Append(ch);
if (ch == '\\')
{
ch = Read();
foreach (System.Tuple<char,char> repl in escapeCharacters){
if (repl.Item1 == ch){
sb.Append(repl.Item2);
break;
}
}
if (ch == 'u'){
char[] hex = Read(4);
sb.Append("_");
Console.WriteLine("JSON WARNING: UNICODE ESCAPE SEQUENCES ARE NOT IMPLEMENTED YET");
}
} else {
sb.Append(ch);
}
}

273
JSON.cs
View File

@ -2,65 +2,266 @@
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Collections;
using System.Security.Cryptography;
namespace sharp.json
{
public abstract class JSON
public delegate object JSONActivationDelegate(Type t);
public abstract class JSON : IEnumerable<JSON>
{
List<string> keys = new List<string>();
List<JSON> values = new List<JSON>();
public virtual double Double { get { throw new NotImplementedException(); } }
public virtual long Integer { get { throw new NotImplementedException(); } }
public virtual string String { get { throw new NotImplementedException(); } }
public virtual bool Boolean { get { throw new NotImplementedException(); } }
public JSON this[int n] {
get {
return values[n];
}
set{
values[n] = value;
}
public virtual JSON this[int n]
{
get { throw new NotImplementedException(String.Format("{0} has no numbered elements",GetType().Name)); }
set { throw new NotImplementedException(String.Format("{0} has no numbered elements",GetType().Name)); }
}
public JSON this[string name] {
get {
return values[keys.IndexOf(name)];
}
set{
if (keys.Contains(name)){
values[keys.IndexOf(name)] = value;
} else {
keys.Add(name);
values.Add(value);
}
}
public virtual JSON this[string name] {
get { throw new NotImplementedException(String.Format("{0} has no named elements", GetType().Name)); }
set { throw new NotImplementedException(String.Format("{0} has no named elements", GetType().Name)); }
}
public string[] Keys {
get { return this.keys.ToArray(); }
}
public JSON[] Values {
get { return this.values.ToArray(); }
public virtual int Count { get { return 0; } }
public virtual bool Contains(object o){
return false;
}
public void Add(JSON element){
this.values.Add(element);
public virtual void Add(JSON child)
{
throw new NotImplementedException(String.Format("{0} has no numbered elements", GetType().Name));
}
public virtual bool isTrue(){
return this.JSONType == JSONTypes.True;
public virtual void Remove(JSON child)
{
throw new NotImplementedException(String.Format("{0} has no numbered elements", GetType().Name));
}
public int Count { get { return values.Count; } }
public JSONTypes JSONType { get; private set; }
protected JSON(JSONTypes type){
JSONType = type;
}
public abstract string prettyPrint(int d);
public abstract string[] prettyPrint();
public override abstract string ToString();
public static JSON parse(String jsonSource){
return new ByteParser(jsonSource).parse();
public string prettyFormat(){
return String.Join("\n", prettyPrint());
}
public static implicit operator JSON(Double src)
{
return new JSONNumber(src);
}
public static implicit operator JSON(int src)
{
return new JSONNumber(src);
}
public static implicit operator JSON(string text)
{
return new JSONString(text);
}
public static implicit operator JSON(bool b)
{
return b ? JSONSpecial.True : JSONSpecial.False;
}
public T To<T>(){
object o = Create(typeof(T));
return (T)o;
}
public void WriteTo(Stream stream){
byte[] data = Encoding.ASCII.GetBytes(ToString());
stream.Write(data,0,data.Length);
}
public void WriteTo(String filename)
{
FileStream fs = new FileStream(filename, FileMode.Create);
WriteTo(fs);
fs.Close();
}
public static JSON ReadFrom(string filename){
JSONParser parser = new JSONParser();
string source = File.ReadAllText(filename);
return parser.Parse(source);
}
private object Create(Type t)
{
if (t.IsPrimitive || (t == typeof(string)) )
{
return CreatePrimitive(t);
}
if (this.JSONType == JSONTypes.Object)
{
return CreateObject(t);
}
if ((this.JSONType == JSONTypes.Array) && (t.IsArray))
{
return CreateArray(t);
}
throw new InvalidCastException(String.Format("JSON {0} can't be casted to {1}", this.JSONType.ToString(), t.Name));
}
private object CreatePrimitive(Type t){
if ((this.JSONType == JSONTypes.Null)){
return null;
}
if ((this.JSONType == JSONTypes.Array) || (this.JSONType == JSONTypes.Object)){
throw new InvalidCastException(String.Format("JSON {0} can't be casted to {1}",this.JSONType.ToString(),t.Name));
}
if (t.Equals(typeof(int)) || t.Equals(typeof(long)) || t.Equals(typeof(short))){
return (object)this.Integer;
}
if (t.Equals(typeof(double)) || t.Equals(typeof(float)))
{
return (object)this.Double;
}
if (t.Equals(typeof(string)))
{
return (object)this.String;
}
if (t.Equals(typeof(Boolean)))
{
return (object)this.Boolean;
}
throw new Exception(String.Format("Unsupported primitive type",t.Name));
}
private object CreateObject(Type t){
if (t.GetConstructor(new Type[] { typeof(JSON) } ) != null){
return Activator.CreateInstance(t, this);
}
object instance = Activator.CreateInstance(t);
Dictionary<string, FieldPropertyInfo> assignedFields = new Dictionary<string, FieldPropertyInfo>();
foreach (FieldInfo fi in t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
foreach (JSONField f in fi.GetCustomAttributes<JSONField>())
{
if (this.Contains(f.Alias))
{
if (!assignedFields.ContainsKey(f.Alias) || assignedFields[f.Alias].IsAutoAssigned){
assignedFields[f.Alias] = new FieldPropertyInfo(fi, false);
break;
}
}
}
if (!assignedFields.ContainsKey(fi.Name) && this.Contains(fi.Name)){
assignedFields[fi.Name] = new FieldPropertyInfo(fi, true);
}
}
foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
foreach (JSONField f in pi.GetCustomAttributes<JSONField>())
{
if (this.Contains(f.Alias))
{
if (!assignedFields.ContainsKey(f.Alias) || assignedFields[f.Alias].IsAutoAssigned)
{
assignedFields[f.Alias] = new FieldPropertyInfo(pi, false);
break;
}
}
}
if (!assignedFields.ContainsKey(pi.Name) && this.Contains(pi.Name))
{
assignedFields[pi.Name] = new FieldPropertyInfo(pi, true);
}
}
foreach (KeyValuePair<string,FieldPropertyInfo> e in assignedFields){
e.Value.setValue(instance, this[e.Key].Create(e.Value.ValueType));
}
return instance;
}
private object CreateArray(Type t)
{
Array a = Array.CreateInstance(t.GetElementType(), this.Count);
for (int n = 0; n < this.Count;n++){
a.SetValue(this[n].Create(t.GetElementType()),n);
}
return a;
}
public virtual IEnumerator<JSON> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)GetEnumerator();
}
struct FieldPropertyInfo {
public bool IsAutoAssigned { get; set; }
FieldInfo FieldInfo { get; set; }
PropertyInfo PropertyInfo { get; set; }
public FieldPropertyInfo(PropertyInfo propertyInfo,bool autoAssigned)
{
this.IsAutoAssigned = autoAssigned;
this.PropertyInfo = propertyInfo;
this.FieldInfo = null;
}
public FieldPropertyInfo(FieldInfo fieldInfo,bool autoAssigned)
{
this.IsAutoAssigned = autoAssigned;
this.PropertyInfo = null;
this.FieldInfo = fieldInfo;
}
public void setValue(object inst,object value){
if (PropertyInfo != null){
PropertyInfo.SetValue(inst,value);
} else if (FieldInfo != null){
FieldInfo.SetValue(inst,value);
}
}
public Type ValueType {
get {
if (PropertyInfo != null){
return PropertyInfo.PropertyType;
} else if (FieldInfo != null){
return FieldInfo.FieldType;
}
return null;
}
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Text;
using System.Collections.Generic;
@ -7,31 +7,95 @@ namespace sharp.json
public class JSONArray : JSON
{
public JSONArray()
:base(JSONTypes.Array){}
public override bool isTrue()
: base(JSONTypes.Array) { }
List<JSON> values = new List<JSON>();
public override bool Boolean
{
throw new NotImplementedException();
get { return values.Count > 0; }
}
public override string prettyPrint(int d = 0)
public override JSON this[int n]
{
return ToString();
get
{
return values[n];
}
set
{
values[n] = value;
}
}
public override int Count
{
get
{
return this.values.Count;
}
}
public override bool Contains(object o)
{
return this.values.Contains((JSON)o);
}
public override void Add(JSON child)
{
this.values.Add(child);
}
public override void Remove(JSON child)
{
this.values.Remove(child);
}
public override string[] prettyPrint()
{
List<string> lines = new List<string>();
lines.Add("[");
for (int i = 0; i < this.values.Count; i++)
{
JSON cv = this.values[i];
string[] clines = cv.prettyPrint();
for (int n = 0; n < clines.Length; n++)
{
lines.Add(String.Format(" {0}{1}", clines[n], (n < clines.Length - 1) || (i == this.values.Count - 1) ? "" : ","));
}
}
lines.Add("]");
return lines.ToArray();
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("[");
for (int n=0;n<this.Count;n++)
for (int n = 0; n < this.Count; n++)
{
sb.Append(this[n].ToString());
if (n+1 < this.Count){
if (n + 1 < this.Count)
{
sb.Append(",");
}
}
sb.Append("]");
return sb.ToString();
}
public override IEnumerator<JSON> GetEnumerator()
{
return this.values.GetEnumerator();
}
}
}

9
JSONField.cs 100644
View File

@ -0,0 +1,9 @@
using System;
namespace sharp.json
{
public class JSONField : Attribute
{
public string Alias { get; set; }
}
}

View File

@ -1,4 +1,6 @@
using System;
using System;
using System.Globalization;
using System.Reflection;
namespace sharp.json
{
public class JSONNumber: JSON
@ -25,18 +27,68 @@ namespace sharp.json
doubleValue = d;
}
public override string prettyPrint(int d = 0)
public override double Double
{
if (Double.IsNaN(doubleValue)){
return this.intValue.ToString();
} else {
return this.doubleValue.ToString();
get
{
if (!Double.IsNaN(doubleValue)){
return doubleValue;
} else {
return (double)intValue;
}
}
}
public override long Integer
{
get
{
if (!Double.IsNaN(doubleValue)){
return (int)doubleValue;
} else {
return intValue;
}
}
}
public override string String
{
get
{
if (!Double.IsNaN(doubleValue))
{
return doubleValue.ToString();
}
else
{
return intValue.ToString();
}
}
}
public override string[] prettyPrint()
{
return new string[] { ToString() };
}
public override string ToString()
{
return this.prettyPrint(0);
if (Double.IsNaN(doubleValue))
{
return this.intValue.ToString();
}
else
{
return this.doubleValue.ToString(CultureInfo.InvariantCulture);
}
}
public bool IsInteger(){
return Double.IsNaN(doubleValue);
}
}
}

View File

@ -1,6 +1,9 @@
using System;
using System.Text;
using System.Collections.Generic;
using sharp.extensions;
using System.Reflection;
using System.Linq;
namespace sharp.json
{
@ -9,29 +12,53 @@ namespace sharp.json
public JSONObject()
:base(JSONTypes.Object){}
public override bool isTrue()
private Dictionary<string, JSON> values = new Dictionary<string, JSON>();
public override JSON this[string name]
{
throw new NotImplementedException();
get { return this.values[name]; }
set { this.values[name] = value; }
}
public override string prettyPrint(int d = 0)
public override int Count
{
StringBuilder sb = new StringBuilder();
sb.Append("{");
get { return this.values.Count; }
}
string[] keys = Keys;
public override bool Boolean
{
get { return this.values.Count > 0; }
}
public override bool Contains(object o)
{
return this.values.ContainsKey((string)o);
}
public override string[] prettyPrint()
{
List<string> lines = new List<string>();
lines.Add("{");
string[] keys = this.values.Keys.ToArray();
for (int n=0;n<keys.Length;n++)
{
sb.Append(new JSONString(keys[n]));
sb.Append(":");
sb.Append(this[keys[n]].ToString());
if (n+1 < keys.Length){
sb.Append(",");
string[] clines = this[keys[n]].prettyPrint();
lines.Add(String.Format(" {0} : {1}",new JSONString(keys[n]),clines[0]));
foreach (string cline in clines.Segment(1)){
lines.Add(String.Format(" {0}",cline));
}
if (n < keys.Length-1){
lines[lines.Count - 1] += ",";
}
}
sb.Append("}");
return sb.ToString();
lines.Add("}");
return lines.ToArray();
}
@ -40,7 +67,7 @@ namespace sharp.json
StringBuilder sb = new StringBuilder();
sb.Append("{");
string[] keys = Keys;
string[] keys = this.values.Keys.ToArray();
for (int n=0;n<keys.Length;n++)
{
@ -54,5 +81,6 @@ namespace sharp.json
sb.Append("}");
return sb.ToString();
}
}
}

318
JSONParser.cs 100644
View File

@ -0,0 +1,318 @@
using System;
using sharp.parser;
using Microsoft.Win32.SafeHandles;
using System.Globalization;
using System.Net.Mime;
using System.Collections.Generic;
namespace sharp.json
{
public class JSONParser : Parser<JSON>
{
delegate JSON ParseObjectDelegate(TokenQueue tokens);
Dictionary<TokenDefinition, ParseObjectDelegate> parserDelegates = new Dictionary<TokenDefinition, ParseObjectDelegate>();
public JSONParser()
:base(tokenDefinitions)
{
parserDelegates.Add(tString,parseString);
parserDelegates.Add(tNumber,parseNumber);
parserDelegates.Add(tObjectOpen,parseObject);
parserDelegates.Add(tArrayOpen,parseArray);
parserDelegates.Add(tTrue,parseTrue);
parserDelegates.Add(tFalse,parseFalse);
parserDelegates.Add(tNull,parseNull);
}
protected override JSON ParseTokens(Token[] tokens)
{
TokenQueue qtoken = new TokenQueue();
foreach (Token t in tokens){
if (t.Definition != tWhiteSpace){
qtoken.Enqueue(t);
}
}
return parseValue(qtoken);
}
private JSON parseValue(TokenQueue tokens){
foreach (TokenDefinition tdef in this.parserDelegates.Keys){
if (tdef == tokens.Peek().Definition){
return this.parserDelegates[tokens.Peek().Definition](tokens);
}
}
throw new Exception(String.Format("Parser got unexpected token: {0}", tokens.Peek().ToString()));
}
JSON parseString(TokenQueue tokens){
Token t = tokens.Expect(tString);
return new JSONString(t.Value.Substring(1, t.Value.Length - 2));
}
JSON parseNumber(TokenQueue tokens)
{
Token t = tokens.Expect(tNumber);
Double dv = double.Parse(t.Value,CultureInfo.InvariantCulture);
return new JSONNumber(dv);
}
JSON parseObject(TokenQueue tokens)
{
Token t = tokens.Expect(tObjectOpen);
JSONObject jo = new JSONObject();
if (tokens.Peek().Definition == tObjectClose){
tokens.Dequeue();
return jo;
}
do
{
JSONString js = (JSONString)parseString(tokens);
tokens.Expect(tColon);
JSON json = parseValue(tokens);
jo[js.String] = json;
t = tokens.Expect(tObjectClose, tComma);
if (t.Definition == tObjectClose){
break;
}
} while (true);
return jo;
}
JSON parseArray(TokenQueue tokens)
{
Token t = tokens.Expect(tArrayOpen);
JSONArray ja = new JSONArray();
if (tokens.Peek().Definition == tArrayClose)
{
tokens.Dequeue();
return ja;
}
do
{
JSON json = parseValue(tokens);
ja.Add(json);
t = tokens.Expect(tArrayClose, tComma);
if (t.Definition == tArrayClose)
{
break;
}
} while (true);
return ja;
}
JSON parseTrue(TokenQueue tokens)
{
if (tokens.Peek().Definition == tTrue){
Token t = tokens.Dequeue();
return JSONSpecial.True;
}
throw new Exception("Unexpected Token: " + tokens.Peek());
}
JSON parseFalse(TokenQueue tokens)
{
if (tokens.Peek().Definition == tFalse){
Token t = tokens.Dequeue();
return JSONSpecial.False;
}
throw new Exception("Unexpected Token: " + tokens.Peek());
}
JSON parseNull(TokenQueue tokens)
{
if (tokens.Peek().Definition == tNull){
Token t = tokens.Dequeue();
return JSONSpecial.Null;
}
throw new Exception("Unexpected Token: " + tokens.Peek());
}
static bool initializer = initialize();
static TokenDefinition[] tokenDefinitions;
static CharGroup eE = new CharGroup(new char[] { 'e', 'E' } );
static LexerPathSegment null_ll;
static LexerPathSegment null_l;
static LexerPathSegment null_u;
static LexerPathSegment null_n;
static LexerPathSegment true_e;
static LexerPathSegment true_u;
static LexerPathSegment true_r;
static LexerPathSegment true_t;
static LexerPathSegment false_e;
static LexerPathSegment false_s;
static LexerPathSegment false_l;
static LexerPathSegment false_a;
static LexerPathSegment false_f;
static LexerPathSegment ws;
static TokenDefinition tNumber;
static TokenDefinition tString;
static TokenDefinition tColon;
static TokenDefinition tComma;
static TokenDefinition tObjectOpen;
static TokenDefinition tObjectClose;
static TokenDefinition tArrayOpen;
static TokenDefinition tArrayClose;
static TokenDefinition tTrue;
static TokenDefinition tFalse;
static TokenDefinition tNull;
static TokenDefinition tWhiteSpace;
static private bool initialize(){
eE = new CharGroup(new char[] { 'e', 'E' });
null_ll = new LexerPathSegment('l', true);
null_l = new LexerPathSegment('l', null_ll);
null_u = new LexerPathSegment('u', null_l);
null_n = new LexerPathSegment('n', null_u);
true_e = new LexerPathSegment('e', true);
true_u = new LexerPathSegment('u', true_e);
true_r = new LexerPathSegment('r', true_u);
true_t = new LexerPathSegment('t', true_r);
false_e = new LexerPathSegment('e', true);
false_s = new LexerPathSegment('s', false_e);
false_l = new LexerPathSegment('l', false_s);
false_a = new LexerPathSegment('a', false_l);
false_f = new LexerPathSegment('f', false_a);
ws = new LexerPathSegment(CharGroup.WS, true);
ws.AddFollower(ws);
tNumber = new TokenDefinition("JSON.number", initializeNumberHead());
tString = new TokenDefinition("JSON.string", initializeStringHead());
tColon = new TokenDefinition("JSON.colon", new LexerPathSegment(':',true));
tComma = new TokenDefinition("JSON.comma", new LexerPathSegment(',',true));
tObjectOpen = new TokenDefinition("JSON.obj.open", new LexerPathSegment('{',true));
tObjectClose = new TokenDefinition("JSON.obj.close", new LexerPathSegment('}',true));
tArrayOpen = new TokenDefinition("JSON.array.open", new LexerPathSegment('[',true));
tArrayClose = new TokenDefinition("JSON.array.close", new LexerPathSegment(']',true));
tTrue = new TokenDefinition("JSON.true", true_t);
tFalse = new TokenDefinition("JSON.false", false_f);
tNull = new TokenDefinition("JSON.null", null_n);
tWhiteSpace = new TokenDefinition("JSON.WhiteSpace",ws);
tokenDefinitions = new TokenDefinition[]{
tWhiteSpace,
tNumber,
tString,
tColon,
tComma,
tObjectOpen,
tObjectClose,
tArrayOpen,
tArrayClose,
tTrue,
tFalse,
tNull
};
return true;
}
static private LexerPathSegment initializeStringHead(){
LexerPathSegment head = new LexerPathSegment('\"');
LexerPathSegment finish = new LexerPathSegment('\"',true);
LexerPathSegment backslash = new LexerPathSegment('\\');
LexerPathSegment control = new LexerPathSegment(new char[] { '\"','\\','/','b','f','n','r','t'} );
LexerPathSegment u4 = new LexerPathSegment(CharGroup.hexdigits);
LexerPathSegment u3 = new LexerPathSegment(CharGroup.hexdigits,u4);
LexerPathSegment u2 = new LexerPathSegment(CharGroup.hexdigits,u3);
LexerPathSegment u1 = new LexerPathSegment(CharGroup.hexdigits,u2);
LexerPathSegment ucontrol = new LexerPathSegment('u',u1);
CharGroup anyChar = new CharGroup((char)0x20, (char)0xff) - backslash.CharGroup - finish.CharGroup;
LexerPathSegment any = new LexerPathSegment(anyChar);
head.AddFollower(finish);
head.AddFollower(any);
head.AddFollower(backslash);
any.AddFollower(any);
any.AddFollower(backslash);
any.AddFollower(finish);
backslash.AddFollower(control);
backslash.AddFollower(ucontrol);
control.AddFollower(any);
control.AddFollower(backslash);
control.AddFollower(finish);
u4.AddFollower(any);
u4.AddFollower(backslash);
u4.AddFollower(finish);
return head;
}
static private LexerPathSegment initializeNumberHead()
{
LexerPathSegment head = new LexerPathSegment();
LexerPathSegment minus = new LexerPathSegment(CharGroup.minus);
LexerPathSegment zero = new LexerPathSegment('0',true);
LexerPathSegment d19 = new LexerPathSegment('1', '9', true);
LexerPathSegment digit_a = new LexerPathSegment(CharGroup.digit,true);
LexerPathSegment digit_b = new LexerPathSegment(CharGroup.digit,true);
LexerPathSegment digit_c = new LexerPathSegment(CharGroup.digit,true);
LexerPathSegment dot = new LexerPathSegment('.');
LexerPathSegment ee = new LexerPathSegment(eE);
LexerPathSegment plusminus = new LexerPathSegment(CharGroup.plusminus);
head.AddFollower(minus);
head.AddFollower(zero);
head.AddFollower(d19);
minus.AddFollower(zero);
minus.AddFollower(d19);
zero.AddFollower(dot);
zero.AddFollower(ee);
d19.AddFollower(digit_a);
d19.AddFollower(dot);
d19.AddFollower(ee);
digit_a.AddFollower(digit_a);
digit_a.AddFollower(dot);
digit_a.AddFollower(ee);
dot.AddFollower(digit_b);
digit_b.AddFollower(digit_b);
digit_b.AddFollower(ee);
ee.AddFollower(digit_c);
ee.AddFollower(plusminus);
digit_c.AddFollower(digit_c);
return head;
}
}
}

28
JSONSerializer.cs 100644
View File

@ -0,0 +1,28 @@
using System;
namespace sharp.json
{
public static class JSONSerializer
{
public static void Apply(JSON json,Object o){
Type t = o.GetType();
if (t.IsPrimitive){
ApplyPrimitive(json,o);
} else {
ApplyClass(json, o);
}
}
public static void ApplyPrimitive(JSON json,Object o){
}
public static void ApplyClass(JSON json,Object o){
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
namespace sharp.json
{
public class JSONSpecial: JSON
@ -12,12 +12,12 @@ namespace sharp.json
{
}
public override bool isTrue()
public override string[] prettyPrint()
{
return (JSONType == JSONTypes.True);
return new string[] { ToString() };
}
public override string prettyPrint(int d = 0)
public override string ToString()
{
switch (JSONType){
case JSONTypes.Null:
@ -30,9 +30,24 @@ namespace sharp.json
throw new NotImplementedException("JSON Special Type badly wrong....");
}
public override string ToString()
public override bool Boolean
{
return prettyPrint();
get
{
return this == True;
}
}
public override string String
{
get
{
if (this == Null){
return null;
}
return base.String;
}
}
}
}

View File

@ -1,5 +1,6 @@
using System;
using System;
using System.Text;
using sharp.extensions;
namespace sharp.json
{
@ -30,14 +31,30 @@ namespace sharp.json
this.value = value;
}
public override string prettyPrint(int d = 0)
public override string String
{
return string.Format("\"{0}\"",escape(value));
get { return this.value; }
}
public override double Double
{
get { return Double.Parse(this.value); }
}
public override long Integer
{
get { return long.Parse(this.value); }
}
public override string[] prettyPrint()
{
return new string[] { ToString() };
}
public override string ToString()
{
return prettyPrint();
return String.Format("\"{0}\"",escape(this.value));
}
public static string escape(string source){
@ -46,7 +63,7 @@ namespace sharp.json
if ((ch >= 0x20) && (ch < 128)){
sb.Append(ch);
} else if (ch < 0x20){
foreach (Tuple<char,char> repl in escapeCharacters){
foreach (System.Tuple<char,char> repl in escapeCharacters){
if (repl.Item2 == ch){
sb.Append("\\");
sb.Append(repl.Item1);
@ -62,5 +79,40 @@ namespace sharp.json
}
return sb.ToString();
}
public static string unescape(string source)
{
StringBuilder sb = new StringBuilder();
CharEnumerator ce = source.GetEnumerator();
char[] hex = new char[4];
while (ce.MoveNext()){
if (ce.Current == '\\'){
ce.MoveNext();
foreach (System.Tuple<char, char> repl in escapeCharacters)
{
if (repl.Item1 == ce.Current)
{
sb.Append(repl.Item2);
break;
}
}
if (ce.Current == 'u'){
for (int n = 0; n < 4;n++){
ce.MoveNext();
hex[3 - n] = ce.Current;
}
sb.Append((char)( HexString.toBytes(hex).toUInt32()[0] ));
}
} else {
sb.Append(ce.Current);
}
}
return sb.ToString();
}
}
}

44
JSONWebRequest.cs 100644
View File

@ -0,0 +1,44 @@
using System;
using sharp.extensions;
using System.Net;
using sharp.webclient;
using System.IO;
using System.Collections.Generic;
namespace sharp.json
{
public class JSONWebRequest
{
private static JSONParser jsonParser = new JSONParser();
public static JSON Call(string url){
return Call(url, null);
}
public static JSON Call(string url, JSON request)
{
return Call(url, request, null);
}
public static JSON Call(string url, JSON request, IDictionary<string,string> headers)
{
HttpRequest req = new HttpRequest(url);
if (request != null){
byte[] rbody = request.ToString().toBytes();
req.RequestStream.Write(rbody,0,rbody.Length);
}
if (headers != null)
{
foreach (string hname in headers.Keys)
{
req.setHeader(hname, headers[hname]);
}
}
HttpResponse response = req.Send();
return jsonParser.Parse(response.ContentText);
}
}
}

View File

@ -2,6 +2,7 @@
using System.IO;
using sharp.json;
using sharp.parser;
namespace json.test
{
@ -17,19 +18,17 @@ namespace json.test
public static void Main(string[] args)
{
JSON json;
JSONParser jsonparser = new JSONParser();
Console.WriteLine("JSON test Patterns:");
Console.WriteLine();
foreach (string src in sources){
json = JSON.parse(src);
Console.WriteLine("SOURCE: {0}",src);
Console.WriteLine("PARSED: {0}",json.ToString());
Console.WriteLine("REPARSED: {0}",JSON.parse(json.ToString()).ToString());
json = jsonparser.Parse(src);
Console.WriteLine("NEW PARSER: {0}",json.ToString());
}
json = JSON.parse(File.ReadAllText("test.json"));
json = jsonparser.Parse(File.ReadAllText("test.json"));
Console.WriteLine("");
Console.WriteLine("test.json file:");
Console.WriteLine("PARSED: {0}",json.ToString());

View File

@ -7,7 +7,7 @@
<OutputType>Exe</OutputType>
<RootNamespace>json.test</RootNamespace>
<AssemblyName>json.test</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -38,6 +38,10 @@
<Project>{D9342117-3249-4D8B-87C9-51A50676B158}</Project>
<Name>sharp.json</Name>
</ProjectReference>
<ProjectReference Include="..\..\sharp-parser\sharp.parser.csproj">
<Project>{32267133-ADB7-4A85-8CF1-03CBDF53715C}</Project>
<Name>sharp.parser</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="test.json">

View File

@ -39,12 +39,28 @@
<Compile Include="JSONString.cs" />
<Compile Include="JSONTypes.cs" />
<Compile Include="JSONNumber.cs" />
<Compile Include="JSONWebRequest.cs" />
<Compile Include="JSONSerializer.cs" />
<Compile Include="JSONParser.cs" />
<Compile Include="JSONField.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
<Name>sharp.extensions</Name>
</ProjectReference>
<ProjectReference Include="..\sharp-webclient\sharp.webclient.csproj">
<Project>{01E98E3B-9462-4CF1-8421-4789763FBAA1}</Project>
<Name>sharp.webclient</Name>
</ProjectReference>
<ProjectReference Include="..\sharp-parser\sharp.parser.csproj">
<Project>{32267133-ADB7-4A85-8CF1-03CBDF53715C}</Project>
<Name>sharp.parser</Name>
</ProjectReference>
<ProjectReference Include="..\sharp-contracts\sharp.contracts.csproj">
<Project>{56733EC1-7D97-48D0-AA4C-98EA624A5A21}</Project>
<Name>sharp.contracts</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>