Mercurial > pub > ImplabNet
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 } |