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