##// END OF EJS Templates
sync
sync

File last commit:

r208:7d07503621fe v2
r222:98eeb63cedb2 default
Show More
JSONScanner.cs
109 lines | 4.7 KiB | text/x-csharp | CSharpLexer
cin
DFA refactoring
r165 using System;
cin
JSON moved to Formats namespace...
r163 using System.Globalization;
cin
DFA refactoring
r165 using Implab.Automaton;
cin
rewritten the text scanner
r176 using System.Text;
using Implab.Components;
using System.IO;
cin
JSON moved to Formats namespace...
r163
cin
DFA refactoring
r165 namespace Implab.Formats.JSON {
cin
JSON moved to Formats namespace...
r163 /// <summary>
/// Сканнер (лексер), разбивающий поток символов на токены JSON.
/// </summary>
cin
rewritten the text scanner
r176 public class JSONScanner : Disposable {
readonly StringBuilder m_builder = new StringBuilder();
cin
sync
r179 readonly ScannerContext<JSONGrammar.TokenType> m_jsonContext = JSONGrammar.Instance.JsonExpression;
readonly ScannerContext<JSONGrammar.TokenType> m_stringContext = JSONGrammar.Instance.JsonStringExpression;
cin
rewritten the text scanner
r176
readonly TextScanner m_scanner;
cin
JSON moved to Formats namespace...
r163
/// <summary>
/// Создает новый экземпляр сканнера
/// </summary>
cin
rewritten the text scanner
r176 public JSONScanner(string text) {
Safe.ArgumentNotEmpty(text, "text");
m_scanner = new StringScanner(text);
}
public JSONScanner(TextReader reader, int bufferMax, int chunkSize) {
Safe.ArgumentNotNull(reader, "reader");
cin
refactoring
r177 m_scanner = new ReaderScanner(reader, bufferMax, chunkSize);
cin
JSON moved to Formats namespace...
r163 }
cin
refactoring complete, JSONParser rewritten
r180 public JSONScanner(TextReader reader) : this(reader, 1024*1024, 1024){
}
cin
JSON moved to Formats namespace...
r163 /// <summary>
/// Читает следующий лексический элемент из входных данных.
/// </summary>
/// <param name="tokenValue">Возвращает значение прочитанного токена.</param>
/// <param name="tokenType">Возвращает тип прочитанного токена.</param>
/// <returns><c>true</c> - чтение произведено успешно. <c>false</c> - достигнут конец входных данных</returns>
/// <remarks>В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е.
/// в строках обрабатываются экранированные символы, числа становтся типа double.</remarks>
public bool ReadToken(out object tokenValue, out JsonTokenType tokenType) {
cin
rewritten the text scanner
r176 JSONGrammar.TokenType[] tag;
cin
fixed DFA optimization, JSON is fully functional
r183 while (m_jsonContext.Execute(m_scanner, out tag)) {
cin
rewritten the text scanner
r176 switch (tag[0]) {
cin
JSON moved to Formats namespace...
r163 case JSONGrammar.TokenType.StringBound:
tokenValue = ReadString();
tokenType = JsonTokenType.String;
break;
case JSONGrammar.TokenType.Number:
cin
rewritten the text scanner
r176 tokenValue = Double.Parse(m_scanner.GetTokenValue(), CultureInfo.InvariantCulture);
cin
JSON moved to Formats namespace...
r163 tokenType = JsonTokenType.Number;
break;
cin
fixed DFA optimization, JSON is fully functional
r183 case JSONGrammar.TokenType.Whitespace:
continue;
cin
JSON moved to Formats namespace...
r163 default:
cin
rewritten the text scanner
r176 tokenType = (JsonTokenType)tag[0];
tokenValue = m_scanner.GetTokenValue();
cin
JSON moved to Formats namespace...
r163 break;
}
return true;
}
tokenValue = null;
tokenType = JsonTokenType.None;
return false;
}
string ReadString() {
int pos = 0;
cin
refactoring
r177 var buf = new char[6]; // the buffer for unescaping chars
cin
rewritten the text scanner
r176
JSONGrammar.TokenType[] tag;
m_builder.Clear();
cin
refactoring
r177 while (m_stringContext.Execute(m_scanner, out tag)) {
cin
rewritten the text scanner
r176 switch (tag[0]) {
cin
JSON moved to Formats namespace...
r163 case JSONGrammar.TokenType.StringBound:
cin
rewritten the text scanner
r176 return m_builder.ToString();
cin
JSON moved to Formats namespace...
r163 case JSONGrammar.TokenType.UnescapedChar:
cin
rewritten the text scanner
r176 m_scanner.CopyTokenTo(m_builder);
cin
JSON moved to Formats namespace...
r163 break;
cin
rewritten the text scanner
r176 case JSONGrammar.TokenType.EscapedUnicode: // \xXXXX - unicode escape sequence
m_scanner.CopyTokenTo(buf, 0);
m_builder.Append(StringTranslator.TranslateHexUnicode(buf, 2));
cin
JSON moved to Formats namespace...
r163 pos++;
break;
cin
rewritten the text scanner
r176 case JSONGrammar.TokenType.EscapedChar: // \t - escape sequence
m_scanner.CopyTokenTo(buf, 0);
m_builder.Append(StringTranslator.TranslateEscapedChar(buf[1]));
cin
JSON moved to Formats namespace...
r163 break;
}
}
throw new ParserException("Unexpected end of data");
}
cin
refactoring
r177
protected override void Dispose(bool disposing) {
if (disposing)
Safe.Dispose(m_scanner);
base.Dispose(disposing);
}
cin
JSON moved to Formats namespace...
r163 }
}