##// END OF EJS Templates
runnable component, work in progress
runnable component, work in progress

File last commit:

r183:4f82e0f161c3 ref20160224
r185:822aab37b107 ref20160224
Show More
JSONGrammar.cs
121 lines | 4.8 KiB | text/x-csharp | CSharpLexer
cin
JSON moved to Formats namespace...
r163 using System.Linq;
using Implab.Automaton.RegularExpressions;
cin
DFA refactoring
r165 using System;
cin
Working on text scanner
r172 using Implab.Automaton;
cin
refactoring complete, JSONParser rewritten
r180 using Implab.Components;
cin
JSON moved to Formats namespace...
r163
namespace Implab.Formats.JSON {
cin
working on JSON parser
r178 class JSONGrammar : Grammar<char> {
cin
JSON moved to Formats namespace...
r163 public enum TokenType {
None,
BeginObject,
EndObject,
BeginArray,
EndArray,
String,
Number,
Literal,
NameSeparator,
ValueSeparator,
cin
fixed DFA optimization, JSON is fully functional
r183 Whitespace,
cin
JSON moved to Formats namespace...
r163
StringBound,
EscapedChar,
UnescapedChar,
cin
rewritten the text scanner
r176 EscapedUnicode
cin
JSON moved to Formats namespace...
r163 }
cin
refactoring complete, JSONParser rewritten
r180 static LazyAndWeak<JSONGrammar> _instance = new LazyAndWeak<JSONGrammar>(() => new JSONGrammar());
cin
DFA refactoring
r165
public static JSONGrammar Instance {
get { return _instance.Value; }
}
cin
working on JSON parser
r178 readonly ScannerContext<TokenType> m_jsonExpression;
readonly ScannerContext<TokenType> m_stringExpression;
cin
refactoring complete, JSONParser rewritten
r180 readonly CharAlphabet m_defaultAlphabet = new CharAlphabet();
cin
JSON moved to Formats namespace...
r163
public JSONGrammar() {
DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9'));
var digit9 = SymbolRangeToken('1', '9');
var zero = SymbolToken('0');
var digit = zero.Or(digit9);
var dot = SymbolToken('.');
var minus = SymbolToken('-');
var sign = SymbolSetToken('-', '+');
var expSign = SymbolSetToken('e', 'E');
var letters = SymbolRangeToken('a', 'z');
var integer = zero.Or(digit9.Cat(digit.EClosure()));
var frac = dot.Cat(digit.Closure());
var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure());
var quote = SymbolToken('"');
var backSlash = SymbolToken('\\');
var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r');
var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4));
var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure();
var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace);
var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace);
var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace);
var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace);
var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace);
var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace);
var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional());
var literal = letters.Closure();
var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x));
var jsonExpression =
number.Tag(TokenType.Number)
.Or(literal.Tag(TokenType.Literal))
.Or(quote.Tag(TokenType.StringBound))
.Or(beginObject.Tag(TokenType.BeginObject))
.Or(endObject.Tag(TokenType.EndObject))
.Or(beginArray.Tag(TokenType.BeginArray))
.Or(endArray.Tag(TokenType.EndArray))
.Or(nameSep.Tag(TokenType.NameSeparator))
cin
fixed DFA optimization, JSON is fully functional
r183 .Or(valueSep.Tag(TokenType.ValueSeparator))
.Or(SymbolSetToken('\n', '\r', '\t', ' ').Closure().Tag(TokenType.Whitespace));
cin
JSON moved to Formats namespace...
r163
var jsonStringExpression =
quote.Tag(TokenType.StringBound)
.Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar))
.Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode))
.Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
cin
working on JSON parser
r178 m_jsonExpression = BuildScannerContext<TokenType>(jsonExpression);
m_stringExpression = BuildScannerContext<TokenType>(jsonStringExpression);
cin
JSON moved to Formats namespace...
r163 }
cin
refactoring complete, JSONParser rewritten
r180 protected override IAlphabetBuilder<char> AlphabetBuilder {
get {
return m_defaultAlphabet;
}
}
cin
working on JSON parser
r178 public ScannerContext<TokenType> JsonExpression {
cin
JSON moved to Formats namespace...
r163 get {
cin
working on JSON parser
r178 return m_jsonExpression;
cin
JSON moved to Formats namespace...
r163 }
}
cin
working on JSON parser
r178 public ScannerContext<TokenType> JsonStringExpression {
cin
JSON moved to Formats namespace...
r163 get {
cin
working on JSON parser
r178 return m_stringExpression;
cin
JSON moved to Formats namespace...
r163 }
}
cin
DFA refactoring
r165
cin
working on JSON parser
r178 Token SymbolRangeToken(char start, char stop) {
cin
pretty print DFA, the minimization is still buggy
r182 return SymbolToken(Enumerable.Range(start, stop - start + 1).Select(x => (char)x));
cin
DFA refactoring
r165 }
cin
Working on text scanner
r172
cin
refactoring complete, JSONParser rewritten
r180 protected override IndexedAlphabetBase<char> CreateAlphabet() {
cin
Working on text scanner
r172 return new CharAlphabet();
}
cin
DFA refactoring
r165
cin
JSON moved to Formats namespace...
r163 }
}