Mercurial > pub > ImplabNet
comparison Implab/JSON/JSONGrammar.cs @ 55:c0bf853aa04f
Added initial JSON support
+JSONParser
+JSONWriter
author | cin |
---|---|
date | Sun, 15 Jun 2014 19:39:11 +0400 |
parents | |
children | d67b95eddaf4 |
comparison
equal
deleted
inserted
replaced
51:2c332a9c64c0 | 55:c0bf853aa04f |
---|---|
1 using Implab.Parsing; | |
2 using System; | |
3 using System.Collections.Generic; | |
4 using System.Linq; | |
5 using System.Text; | |
6 using System.Threading.Tasks; | |
7 | |
8 namespace Implab.JSON { | |
9 internal class JSONGrammar : Grammar<JSONGrammar> { | |
10 public enum TokenType : int{ | |
11 None, | |
12 BeginObject, | |
13 EndObject, | |
14 BeginArray, | |
15 EndArray, | |
16 String, | |
17 Number, | |
18 Literal, | |
19 NameSeparator, | |
20 ValueSeparator, | |
21 | |
22 StringBound, | |
23 EscapedChar, | |
24 UnescapedChar, | |
25 EscapedUnicode, | |
26 | |
27 Minus, | |
28 Plus, | |
29 Sign, | |
30 Integer, | |
31 Dot, | |
32 Exp | |
33 } | |
34 | |
35 readonly CDFADefinition m_jsonDFA; | |
36 readonly CDFADefinition m_stringDFA; | |
37 | |
38 public JSONGrammar() { | |
39 DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x)); | |
40 var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9')); | |
41 var digit9 = SymbolRangeToken('1', '9'); | |
42 var zero = SymbolToken('0'); | |
43 var digit = zero.Or(digit9); | |
44 var dot = SymbolToken('.'); | |
45 var minus = SymbolToken('-'); | |
46 var sign = SymbolSetToken('-', '+'); | |
47 var expSign = SymbolSetToken('e', 'E'); | |
48 var letters = SymbolRangeToken('a', 'z'); | |
49 var integer = zero.Or(digit9.Cat(digit.EClosure())); | |
50 var frac = dot.Cat(digit.Closure()); | |
51 var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure()); | |
52 var quote = SymbolToken('"'); | |
53 var backSlash = SymbolToken('\\'); | |
54 var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r'); | |
55 var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4)); | |
56 var escape = backSlash.Cat(specialEscapeChars.Or(unicodeEspace)); | |
57 var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure(); | |
58 var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace); | |
59 var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace); | |
60 var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace); | |
61 var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace); | |
62 var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace); | |
63 var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace); | |
64 | |
65 var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional()); | |
66 var literal = letters.Closure(); | |
67 var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x)); | |
68 var character = unescaped.Or(escape); | |
69 var str = quote.Cat(character.EClosure()).Cat(quote); | |
70 | |
71 | |
72 var jsonExpression = | |
73 number.Tag(TokenType.Number) | |
74 .Or(literal.Tag(TokenType.Literal)) | |
75 .Or(quote.Tag(TokenType.StringBound)) | |
76 .Or(beginObject.Tag(TokenType.BeginObject)) | |
77 .Or(endObject.Tag(TokenType.EndObject)) | |
78 .Or(beginArray.Tag(TokenType.BeginArray)) | |
79 .Or(endArray.Tag(TokenType.EndArray)) | |
80 .Or(nameSep.Tag(TokenType.NameSeparator)) | |
81 .Or(valueSep.Tag(TokenType.ValueSeparator)); | |
82 | |
83 | |
84 var jsonStringExpression = | |
85 quote.Tag(TokenType.StringBound) | |
86 .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar)) | |
87 .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode)) | |
88 .Or(unescaped.Closure().Tag(TokenType.UnescapedChar)); | |
89 | |
90 var jsonNumberExpression = | |
91 minus.Tag(TokenType.Minus) | |
92 .Or(SymbolToken('+').Tag(TokenType.Plus)) | |
93 .Or(digit.Closure().Tag(TokenType.Integer)) | |
94 .Or(dot.Tag(TokenType.Dot)) | |
95 .Or(expSign.Tag(TokenType.Exp)); | |
96 | |
97 m_jsonDFA = BuildDFA(jsonExpression); | |
98 m_stringDFA = BuildDFA(jsonStringExpression); | |
99 } | |
100 | |
101 public CDFADefinition JsonDFA { | |
102 get { | |
103 return m_jsonDFA; | |
104 } | |
105 } | |
106 | |
107 public CDFADefinition JsonStringDFA { | |
108 get { | |
109 return m_stringDFA; | |
110 } | |
111 } | |
112 } | |
113 } |