Mercurial > pub > ImplabNet
comparison Implab.ServiceHost/Unity/TypeReferenceParser.cs @ 267:6b3e5c48131b v3
Working on Unity xml configuration
author | cin |
---|---|
date | Fri, 20 Apr 2018 19:05:12 +0300 |
parents | |
children | 0be8a6ae8307 |
comparison
equal
deleted
inserted
replaced
266:254d1f255d87 | 267:6b3e5c48131b |
---|---|
1 using System; | |
2 using System.Collections.Generic; | |
3 using System.Text.RegularExpressions; | |
4 | |
5 namespace Implab.ServiceHost.Unity { | |
6 public class TypeReferenceParser { | |
7 enum TokenType { | |
8 None, | |
9 | |
10 Word, | |
11 | |
12 Dot, | |
13 | |
14 Comma, | |
15 | |
16 OpenList, | |
17 | |
18 CloseList, | |
19 | |
20 Eof | |
21 } | |
22 | |
23 readonly Regex _tokens = new Regex(@"(\w+)|\s*([\.{},])\s*"); | |
24 | |
25 TokenType m_token; | |
26 | |
27 string m_tokenValue; | |
28 | |
29 int m_pos; | |
30 | |
31 readonly string m_text; | |
32 | |
33 TokenType Token { get { return m_token; } } | |
34 | |
35 string TokenValue { get { return m_tokenValue; } } | |
36 | |
37 public TypeReferenceParser(string text) { | |
38 Safe.ArgumentNotEmpty(text, nameof(text)); | |
39 m_text = text; | |
40 } | |
41 | |
42 bool ReadToken() { | |
43 if (m_pos >= m_text.Length) { | |
44 m_token = TokenType.Eof; | |
45 m_tokenValue = null; | |
46 return false; | |
47 } | |
48 | |
49 var m = _tokens.Match(m_text, m_pos); | |
50 | |
51 if (m.Success) { | |
52 m_pos += m.Length; | |
53 if (m.Groups[1].Success) { | |
54 m_token = TokenType.Word; | |
55 m_tokenValue = m.Groups[1].Value; | |
56 } else if (m.Groups[2].Success) { | |
57 m_tokenValue = null; | |
58 switch (m.Groups[2].Value) { | |
59 case "{": | |
60 m_token = TokenType.OpenList; | |
61 break; | |
62 case "}": | |
63 m_token = TokenType.CloseList; | |
64 break; | |
65 case ".": | |
66 m_token = TokenType.Dot; | |
67 break; | |
68 case ",": | |
69 m_token = TokenType.Comma; | |
70 break; | |
71 } | |
72 } | |
73 return true; | |
74 } | |
75 throw new FormatException($"Failed to parse '{m_text}' at pos {m_pos}"); | |
76 } | |
77 | |
78 public TypeRerefence Pase() { | |
79 | |
80 } | |
81 | |
82 string[] ReadTypeName() { | |
83 var parts = new List<string>(); | |
84 | |
85 string current = null; | |
86 bool stop = false; | |
87 while ((!stop) && ReadToken()) { | |
88 switch (Token) { | |
89 case TokenType.Word: | |
90 if (current != null) | |
91 ThrowUnexpectedToken(); | |
92 current = TokenValue; | |
93 break; | |
94 case TokenType.Dot: | |
95 if (current == null) | |
96 ThrowUnexpectedToken(); | |
97 parts.Add(current); | |
98 current = null; | |
99 break; | |
100 default: | |
101 stop = true; | |
102 break; | |
103 } | |
104 } | |
105 if (current != null) | |
106 parts.Add(current); | |
107 | |
108 if (parts.Count == 0) | |
109 return null; | |
110 | |
111 return parts.ToArray(); | |
112 } | |
113 | |
114 TypeReference ReadTypeReference() { | |
115 | |
116 var parts = ReadTypeName(); | |
117 if (parts == null) | |
118 return null; | |
119 | |
120 var typeReference = new TypeReference { | |
121 Namespace = string.Join(",", parts, 0, parts.Length - 1), | |
122 TypeName = parts[parts.Length - 1] | |
123 }; | |
124 | |
125 switch (Token) { | |
126 case TokenType.Eof: | |
127 break; | |
128 case TokenType.OpenList: | |
129 typeReference.GenericParameters = ReadTypeReferenceList(); | |
130 if(Token != TokenType.CloseList) | |
131 ThrowUnexpectedToken(); | |
132 break; | |
133 default: | |
134 ThrowUnexpectedToken(); | |
135 break; | |
136 } | |
137 | |
138 return typeReference; | |
139 } | |
140 | |
141 TypeReference[] ReadTypeReferenceList() { | |
142 throw new NotImplementedException(); | |
143 } | |
144 | |
145 void ReadDot() { | |
146 if (!ReadToken() || Token != TokenType.Dot) | |
147 ThrowUnexpectedToken(); | |
148 } | |
149 | |
150 void ThrowUnexpectedToken() { | |
151 throw new FormatException($"Unexpected '{Token}' at {m_pos}"); | |
152 } | |
153 | |
154 | |
155 } | |
156 } |