comparison Implab.ServiceHost/Unity/TypeReferenceParser.cs @ 268:0be8a6ae8307 v3

Implemented typereference parser
author cin
date Sun, 22 Apr 2018 15:29:10 +0300
parents 6b3e5c48131b
children ff581cff7003
comparison
equal deleted inserted replaced
267:6b3e5c48131b 268:0be8a6ae8307
1 using System; 1 using System;
2 using System.Collections.Generic; 2 using System.Collections.Generic;
3 using System.Text.RegularExpressions; 3 using System.Text.RegularExpressions;
4 4
5 namespace Implab.ServiceHost.Unity { 5 namespace Implab.ServiceHost.Unity {
6 public class TypeReferenceParser { 6 internal class TypeReferenceParser {
7 enum TokenType { 7 enum TokenType {
8 None, 8 None,
9 9
10 Word, 10 Word,
11 11
18 CloseList, 18 CloseList,
19 19
20 Eof 20 Eof
21 } 21 }
22 22
23 readonly Regex _tokens = new Regex(@"(\w+)|\s*([\.{},])\s*"); 23 readonly Regex _tokens = new Regex(@"(\w+)|\s*([\.{},\+])\s*");
24 24
25 TokenType m_token; 25 TokenType m_token;
26 26
27 string m_tokenValue; 27 string m_tokenValue;
28 28
29 int m_pos; 29 int m_pos;
30 30
31 int m_tokenPos;
32
31 readonly string m_text; 33 readonly string m_text;
32 34
33 TokenType Token { get { return m_token; } } 35 TokenType Token { get { return m_token; } }
34 36
35 string TokenValue { get { return m_tokenValue; } } 37 string TokenValue { get { return m_tokenValue; } }
38
39 int TokenPos { get { return m_tokenPos; } }
36 40
37 public TypeReferenceParser(string text) { 41 public TypeReferenceParser(string text) {
38 Safe.ArgumentNotEmpty(text, nameof(text)); 42 Safe.ArgumentNotEmpty(text, nameof(text));
39 m_text = text; 43 m_text = text;
40 } 44 }
47 } 51 }
48 52
49 var m = _tokens.Match(m_text, m_pos); 53 var m = _tokens.Match(m_text, m_pos);
50 54
51 if (m.Success) { 55 if (m.Success) {
56 m_tokenPos = m_pos;
52 m_pos += m.Length; 57 m_pos += m.Length;
53 if (m.Groups[1].Success) { 58 if (m.Groups[1].Success) {
54 m_token = TokenType.Word; 59 m_token = TokenType.Word;
55 m_tokenValue = m.Groups[1].Value; 60 m_tokenValue = m.Groups[1].Value;
56 } else if (m.Groups[2].Success) { 61 } else if (m.Groups[2].Success) {
61 break; 66 break;
62 case "}": 67 case "}":
63 m_token = TokenType.CloseList; 68 m_token = TokenType.CloseList;
64 break; 69 break;
65 case ".": 70 case ".":
71 case "+":
66 m_token = TokenType.Dot; 72 m_token = TokenType.Dot;
67 break; 73 break;
68 case ",": 74 case ",":
69 m_token = TokenType.Comma; 75 m_token = TokenType.Comma;
70 break; 76 break;
73 return true; 79 return true;
74 } 80 }
75 throw new FormatException($"Failed to parse '{m_text}' at pos {m_pos}"); 81 throw new FormatException($"Failed to parse '{m_text}' at pos {m_pos}");
76 } 82 }
77 83
78 public TypeRerefence Pase() { 84 public TypeReference Parse() {
79 85 var result = ReadTypeReference();
86 if (ReadToken())
87 ThrowUnexpectedToken();
88 return result;
80 } 89 }
81 90
82 string[] ReadTypeName() { 91 string[] ReadTypeName() {
83 var parts = new List<string>(); 92 var parts = new List<string>();
84 93
116 var parts = ReadTypeName(); 125 var parts = ReadTypeName();
117 if (parts == null) 126 if (parts == null)
118 return null; 127 return null;
119 128
120 var typeReference = new TypeReference { 129 var typeReference = new TypeReference {
121 Namespace = string.Join(",", parts, 0, parts.Length - 1), 130 Namespace = string.Join(".", parts, 0, parts.Length - 1),
122 TypeName = parts[parts.Length - 1] 131 TypeName = parts[parts.Length - 1]
123 }; 132 };
124 133
125 switch (Token) { 134 switch (Token) {
126 case TokenType.Eof:
127 break;
128 case TokenType.OpenList: 135 case TokenType.OpenList:
129 typeReference.GenericParameters = ReadTypeReferenceList(); 136 typeReference.GenericParameters = ReadTypeReferenceList();
130 if(Token != TokenType.CloseList) 137 if (Token != TokenType.CloseList)
131 ThrowUnexpectedToken(); 138 ThrowUnexpectedToken();
132 break; 139 ReadToken();
133 default:
134 ThrowUnexpectedToken();
135 break; 140 break;
136 } 141 }
137 142
138 return typeReference; 143 return typeReference;
139 } 144 }
140 145
141 TypeReference[] ReadTypeReferenceList() { 146 TypeReference[] ReadTypeReferenceList() {
142 throw new NotImplementedException(); 147 var list = new List<TypeReference>();
143 }
144 148
145 void ReadDot() { 149 do {
146 if (!ReadToken() || Token != TokenType.Dot) 150 var typeReference = ReadTypeReference();
147 ThrowUnexpectedToken(); 151 list.Add(typeReference);
152 } while (Token == TokenType.Comma);
153
154 return list.ToArray();
148 } 155 }
149 156
150 void ThrowUnexpectedToken() { 157 void ThrowUnexpectedToken() {
151 throw new FormatException($"Unexpected '{Token}' at {m_pos}"); 158 throw new FormatException($"Unexpected '{Token}' at pos {TokenPos}: -->{m_text.Substring(TokenPos, Math.Min(m_text.Length - TokenPos, 10))}");
152 } 159 }
153
154 160
155 } 161 }
156 } 162 }