Last active
March 7, 2016 03:34
-
-
Save kokudori/5252810 to your computer and use it in GitHub Desktop.
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
start = Object | |
value = dynamic | |
namespace = JsonParser | |
Object := UnVisibles '{' UnVisibles ObjectWithKeys UnVisibles '}' UnVisibles | |
`;` `expected = "object"` | |
ObjectWithKey := Identifier Spaces ':' Spaces (Literal / InnerObject) | |
`value = ToPair(results)` | |
ObjectWithKey := String Spaces ':' Spaces (Literal / InnerObject) | |
`value = ToPairByString(results)` | |
ObjectWithKeys := ObjectWithKey (',' UnVisibles ObjectWithKey)* `AddObject(results)` | |
InnerObject := UnVisibles '{' UnVisibles ObjectWithKey (',' UnVisibles ObjectWithKey)* UnVisibles '}' UnVisibles | |
`value = ToObject(results)` | |
Identifier := [a-zA-Z_] [0-9a-zA-Z]* | |
`;` `expected = "identifier"` | |
Literal := String / Number / Boolean / Undefined / Null; | |
Null := 'null' | |
`value = null` `expected = "null"` | |
Undefined := 'undefined' | |
`value = null` `expected = "undefined"` | |
Boolean := 'true' / 'false' | |
`value = ToBoolean(results)` `expected = "boolean"` | |
Number := '-'? [0-9]+ ('.' [0-9]+)? | |
`value = ToNumber(results)` `expected = "number"` | |
String := (["] ([^\r\n"])* ["]) / (['] ([^\r\n'])* [']) | |
`value = ToString(results)` `expected = "string"` | |
UnVisibles := Spaces NewLines Spaces; | |
Spaces := Space*; | |
Space := [ \t] `;` `expected = "whitespace"` | |
NewLines := NewLine*; | |
NewLine := [\r\n] `;` `expected = "newline"` |
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 JsonParser | |
{ | |
static class Helper | |
{ | |
internal static void Each<T>(this IEnumerable<T> source, Action<T> action) | |
{ | |
foreach (var item in source) | |
{ | |
action(item); | |
} | |
} | |
} | |
class Context | |
{ | |
public Dictionary<string, dynamic> Root { get; private set; } | |
public Context() | |
{ | |
Root = new Dictionary<string,dynamic>(); | |
} | |
public void AddObject(string name, dynamic value) | |
{ | |
Root.Add(name, value); | |
} | |
} | |
partial class Parser | |
{ | |
Context context = new Context(); | |
public Dictionary<string, dynamic> Root { get { return context.Root; } } | |
double ToNumber(IEnumerable<Result> results) | |
{ | |
return Double.Parse(String.Join("", results.Select(x => x.Text))); | |
} | |
bool ToBoolean(IEnumerable<Result> results) | |
{ | |
return Boolean.Parse(results.First().Text); | |
} | |
string ToString(IEnumerable<Result> results) | |
{ | |
return String.Join("", | |
results | |
.Skip(1) | |
.TakeWhile(x => x.Text != results.Last().Text) | |
.Select(x => x.Text) | |
); | |
} | |
KeyValuePair<string, dynamic> ToPair(IEnumerable<Result> results) | |
{ | |
if (results.All(x => x.Value == null)) | |
return new KeyValuePair<string, dynamic>(); | |
var value = results.Where(x => x.Value != null).Single().Value; | |
var name = results.First().Text; | |
return new KeyValuePair<string, dynamic>(name, value); | |
} | |
KeyValuePair<string, dynamic> ToPairByString(IEnumerable<Result> results) | |
{ | |
if (results.All(x => x.Value == null)) | |
return new KeyValuePair<string, dynamic>(); | |
var value = results.Where(x => x.Value != null).Skip(1).Single().Value; | |
var name = results.First().Text.Substring(1, results.First().Text.Count() -2); | |
return new KeyValuePair<string, dynamic>(name, value); | |
} | |
Dictionary<string, dynamic> ToObject(IEnumerable<Result> results) | |
{ | |
var jsonObject = new Dictionary<string, dynamic>(); | |
results | |
.Select(x => x.Value) | |
.OfType<KeyValuePair<string, dynamic>>() | |
.Each(x => jsonObject.Add(x.Key, x.Value)); | |
return jsonObject; | |
} | |
void AddObject(IEnumerable<Result> results) | |
{ | |
results | |
.Select(x => x.Value) | |
.OfType<KeyValuePair<string, dynamic>>() | |
.Each(x => context.AddObject(x.Key, x.Value)); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var input = | |
@" | |
{ | |
hoge: 100, | |
piyo: { | |
inner: 'hogehoge', | |
inner2: 23.45 | |
}, | |
fuga: -300, | |
'abc': 100, | |
""bca"": ""aaaa"", | |
'hoge piyo': 'fuga bar' | |
} | |
"; | |
var parser = new Parser(); | |
parser.Parse(input); | |
Console.WriteLine("input"); | |
Console.WriteLine(input); | |
Console.WriteLine("Root['hoge'] == {0}", parser.Root["hoge"]); | |
Console.WriteLine("Root['hoge'].GetType() == {0}", parser.Root["hoge"].GetType()); | |
Console.WriteLine("Root['piyo'].Count == {0}", parser.Root["piyo"].Count); | |
Console.WriteLine("Root['piyo']['inner'] == {0}", parser.Root["piyo"]["inner"]); | |
Console.WriteLine("Root['piyo']['inner'].GetType() == {0}", parser.Root["piyo"]["inner"].GetType()); | |
Console.WriteLine("Root['piyo']['inner2'] == {0}", parser.Root["piyo"]["inner2"]); | |
Console.WriteLine("Root['piyo']['inner2'].GetType() == {0}", parser.Root["piyo"]["inner2"].GetType()); | |
Console.WriteLine("Root['fuga'] == {0}", parser.Root["fuga"]); | |
Console.WriteLine("Root['fuga'].GetType() == {0}", parser.Root["fuga"].GetType()); | |
Console.WriteLine("Root['abc'] == {0}", parser.Root["abc"]); | |
Console.WriteLine("Root['abc'].GetType() == {0}", parser.Root["abc"].GetType()); | |
Console.WriteLine("Root['bca'] == {0}", parser.Root["bca"]); | |
Console.WriteLine("Root['bca'].GetType() == {0}", parser.Root["bca"].GetType()); | |
Console.WriteLine("Root['hoge piyo'] == {0}", parser.Root["hoge piyo"]); | |
Console.WriteLine("Root['hoge piyo'].GetType() == {0}", parser.Root["hoge piyo"].GetType()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
peg-sharp.exe JsonParser.peg
でJsonParser.csが生成されます。peg-shaprについてはこちらを御覧ください。