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