comparison Implab/Formats/JSON/JSONScanner.cs @ 177:a0ff6a0e9c44 ref20160224

refactoring
author cin
date Wed, 23 Mar 2016 01:42:00 +0300
parents 0c3c69fe225b
children 478ef706906a
comparison
equal deleted inserted replaced
176:0c3c69fe225b 177:a0ff6a0e9c44
2 using System.Globalization; 2 using System.Globalization;
3 using Implab.Automaton; 3 using Implab.Automaton;
4 using System.Text; 4 using System.Text;
5 using Implab.Components; 5 using Implab.Components;
6 using System.IO; 6 using System.IO;
7 using Implab.Automaton.RegularExpressions;
8 7
9 namespace Implab.Formats.JSON { 8 namespace Implab.Formats.JSON {
10 /// <summary> 9 /// <summary>
11 /// Сканнер (лексер), разбивающий поток символов на токены JSON. 10 /// Сканнер (лексер), разбивающий поток символов на токены JSON.
12 /// </summary> 11 /// </summary>
13 public class JSONScanner : Disposable { 12 public class JSONScanner : Disposable {
14 readonly StringBuilder m_builder = new StringBuilder(); 13 readonly StringBuilder m_builder = new StringBuilder();
15 14
16 readonly ScannerContext<JSONGrammar.TokenType> m_jsonScanner = JSONGrammar.Instance.JsonDFA; 15 readonly ScannerContext<JSONGrammar.TokenType> m_jsonContext = JSONGrammar.Instance.JsonDFA;
17 readonly ScannerContext<JSONGrammar.TokenType> m_stringScanner = JSONGrammar.Instance.JsonStringDFA; 16 readonly ScannerContext<JSONGrammar.TokenType> m_stringContext = JSONGrammar.Instance.JsonStringDFA;
18 17
19 18
20 readonly TextScanner m_scanner; 19 readonly TextScanner m_scanner;
21 20
22 /// <summary> 21 /// <summary>
29 } 28 }
30 29
31 public JSONScanner(TextReader reader, int bufferMax, int chunkSize) { 30 public JSONScanner(TextReader reader, int bufferMax, int chunkSize) {
32 Safe.ArgumentNotNull(reader, "reader"); 31 Safe.ArgumentNotNull(reader, "reader");
33 32
34 m_scanner = new ReaderScanner(reader); 33 m_scanner = new ReaderScanner(reader, bufferMax, chunkSize);
35 } 34 }
36 35
37 /// <summary> 36 /// <summary>
38 /// Читает следующий лексический элемент из входных данных. 37 /// Читает следующий лексический элемент из входных данных.
39 /// </summary> 38 /// </summary>
42 /// <returns><c>true</c> - чтение произведено успешно. <c>false</c> - достигнут конец входных данных</returns> 41 /// <returns><c>true</c> - чтение произведено успешно. <c>false</c> - достигнут конец входных данных</returns>
43 /// <remarks>В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е. 42 /// <remarks>В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е.
44 /// в строках обрабатываются экранированные символы, числа становтся типа double.</remarks> 43 /// в строках обрабатываются экранированные символы, числа становтся типа double.</remarks>
45 public bool ReadToken(out object tokenValue, out JsonTokenType tokenType) { 44 public bool ReadToken(out object tokenValue, out JsonTokenType tokenType) {
46 JSONGrammar.TokenType[] tag; 45 JSONGrammar.TokenType[] tag;
47 if (m_jsonScanner.Execute(m_scanner, out tag)) { 46 if (m_jsonContext.Execute(m_scanner, out tag)) {
48 switch (tag[0]) { 47 switch (tag[0]) {
49 case JSONGrammar.TokenType.StringBound: 48 case JSONGrammar.TokenType.StringBound:
50 tokenValue = ReadString(); 49 tokenValue = ReadString();
51 tokenType = JsonTokenType.String; 50 tokenType = JsonTokenType.String;
52 break; 51 break;
66 return false; 65 return false;
67 } 66 }
68 67
69 string ReadString() { 68 string ReadString() {
70 int pos = 0; 69 int pos = 0;
71 char[] buf = new char[6]; // the buffer for unescaping chars 70 var buf = new char[6]; // the buffer for unescaping chars
72 71
73 JSONGrammar.TokenType[] tag; 72 JSONGrammar.TokenType[] tag;
74 m_builder.Clear(); 73 m_builder.Clear();
75 74
76 while (m_stringScanner.Execute(m_scanner, out tag)) { 75 while (m_stringContext.Execute(m_scanner, out tag)) {
77 switch (tag[0]) { 76 switch (tag[0]) {
78 case JSONGrammar.TokenType.StringBound: 77 case JSONGrammar.TokenType.StringBound:
79 return m_builder.ToString(); 78 return m_builder.ToString();
80 case JSONGrammar.TokenType.UnescapedChar: 79 case JSONGrammar.TokenType.UnescapedChar:
81 m_scanner.CopyTokenTo(m_builder); 80 m_scanner.CopyTokenTo(m_builder);
87 break; 86 break;
88 case JSONGrammar.TokenType.EscapedChar: // \t - escape sequence 87 case JSONGrammar.TokenType.EscapedChar: // \t - escape sequence
89 m_scanner.CopyTokenTo(buf, 0); 88 m_scanner.CopyTokenTo(buf, 0);
90 m_builder.Append(StringTranslator.TranslateEscapedChar(buf[1])); 89 m_builder.Append(StringTranslator.TranslateEscapedChar(buf[1]));
91 break; 90 break;
92 default:
93 break;
94 } 91 }
95 92
96 } 93 }
97 94
98 throw new ParserException("Unexpected end of data"); 95 throw new ParserException("Unexpected end of data");
99 } 96 }
97
98 protected override void Dispose(bool disposing) {
99 if (disposing)
100 Safe.Dispose(m_scanner);
101 base.Dispose(disposing);
102 }
100 } 103 }
101 } 104 }