##// END OF EJS Templates
Added Skip method to JSON parser to skip contents of the current node
Added Skip method to JSON parser to skip contents of the current node

File last commit:

r55:c0bf853aa04f default
r62:62b440d46313 default
Show More
JSONGrammar.cs
113 lines | 4.4 KiB | text/x-csharp | CSharpLexer
using Implab.Parsing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Implab.JSON {
internal class JSONGrammar : Grammar<JSONGrammar> {
public enum TokenType : int{
None,
BeginObject,
EndObject,
BeginArray,
EndArray,
String,
Number,
Literal,
NameSeparator,
ValueSeparator,
StringBound,
EscapedChar,
UnescapedChar,
EscapedUnicode,
Minus,
Plus,
Sign,
Integer,
Dot,
Exp
}
readonly CDFADefinition m_jsonDFA;
readonly CDFADefinition m_stringDFA;
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 escape = backSlash.Cat(specialEscapeChars.Or(unicodeEspace));
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 character = unescaped.Or(escape);
var str = quote.Cat(character.EClosure()).Cat(quote);
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))
.Or(valueSep.Tag(TokenType.ValueSeparator));
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));
var jsonNumberExpression =
minus.Tag(TokenType.Minus)
.Or(SymbolToken('+').Tag(TokenType.Plus))
.Or(digit.Closure().Tag(TokenType.Integer))
.Or(dot.Tag(TokenType.Dot))
.Or(expSign.Tag(TokenType.Exp));
m_jsonDFA = BuildDFA(jsonExpression);
m_stringDFA = BuildDFA(jsonStringExpression);
}
public CDFADefinition JsonDFA {
get {
return m_jsonDFA;
}
}
public CDFADefinition JsonStringDFA {
get {
return m_stringDFA;
}
}
}
}