Skip to content

Commit 294c239

Browse files
committed
убраны пустые ноды при добавлении; ускорено получение значениий
1 parent fbf15ea commit 294c239

File tree

4 files changed

+183
-199
lines changed

4 files changed

+183
-199
lines changed

src/OneScript.Language/IdentifiersTrie.cs

Lines changed: 67 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,20 @@ public class IdentifiersTrie<T> : IDictionary<string, T>
1717

1818
private class TrieNode
1919
{
20-
public char charL;
21-
public char charU;
22-
public TrieNode sibl;
23-
public TrieNode next;
20+
internal char charL;
21+
internal char charU;
22+
internal TrieNode sibl;
23+
internal TrieNode next;
2424

25-
private T _value;
25+
internal T value;
2626

27-
public T Value
28-
{
29-
get => _value;
30-
set
31-
{
32-
HasValue = true;
33-
_value = value;
34-
}
35-
}
36-
37-
public bool HasValue { get; private set; }
38-
39-
public TrieNode Find(char ch)
27+
internal bool hasValue;
28+
29+
internal TrieNode() { }
30+
internal TrieNode(char ch)
31+
{ charL = char.ToLower(ch); charU = char.ToUpper(ch); }
32+
33+
internal TrieNode Find(char ch)
4034
{
4135
var node = sibl;
4236
while (node != null)
@@ -47,47 +41,46 @@ public TrieNode Find(char ch)
4741
}
4842
return null;
4943
}
50-
51-
}
52-
44+
}
45+
5346
public void Add(string str, T val)
5447
{
5548
var node = _root;
49+
TrieNode key = node;
5650
foreach (char ch in str)
5751
{
58-
var key = node.Find(ch);
59-
if (key == null)
52+
if (node == null)
6053
{
61-
key = new TrieNode
54+
node = new TrieNode(ch);
55+
key.next = node;
56+
key = node;
57+
node = null;
58+
}
59+
else
60+
{
61+
TrieNode last = node;
62+
key = node;
63+
while (key != null && key.charL != ch && key.charU != ch)
64+
{
65+
last = key;
66+
key = key.sibl;
67+
}
68+
if (key == null)
6269
{
63-
charL = char.ToLower(ch),
64-
charU = char.ToUpper(ch),
65-
Value = default(T),
66-
sibl = node.sibl
67-
};
68-
node.sibl = key;
69-
key.next = new TrieNode();
70+
key = new TrieNode(ch);
71+
last.sibl = key;
72+
}
73+
node = key.next;
7074
}
71-
node = key.next;
7275
}
7376

74-
node.Value = val;
77+
key.value = val;
78+
key.hasValue = true;
7579
}
7680

77-
public bool ContainsKey(string key)
78-
{
79-
var node = _root;
80-
foreach (char ch in key)
81-
{
82-
var keyNode = node.Find(ch);
83-
if (keyNode == null)
84-
{
85-
return false;
86-
}
87-
node = keyNode.next;
88-
}
89-
90-
return node.next == null && node.HasValue;
81+
public bool ContainsKey(string str)
82+
{
83+
return TryGetValue(str, out _);
9184
}
9285

9386
public bool Remove(string key)
@@ -96,22 +89,10 @@ public bool Remove(string key)
9689
}
9790

9891
public T Get(string str)
99-
{
100-
var node = _root;
101-
foreach (char ch in str)
102-
{
103-
TrieNode key = node.Find(ch);
104-
if (key == null)
105-
throw new KeyNotFoundException();
106-
107-
node = key.next;
108-
}
109-
110-
if (!node.HasValue)
111-
throw new KeyNotFoundException();
112-
113-
return node.Value;
114-
}
92+
{
93+
return TryGetValue(str, out var value) ? value
94+
: throw new KeyNotFoundException();
95+
}
11596

11697
public T this[string index]
11798
{
@@ -124,27 +105,34 @@ public T this[string index]
124105

125106
public bool TryGetValue(string str, out T value)
126107
{
127-
var node = _root;
108+
TrieNode key = _root;
109+
var node = key.sibl;
128110
foreach (char ch in str)
129-
{
130-
var key = node.Find(ch);
131-
if (key == null)
132-
{
133-
value = default;
134-
return false;
135-
}
136-
111+
{
112+
while (node != null && node.charL != ch && node.charU != ch)
113+
{
114+
node = node.sibl;
115+
}
116+
if (node == null)
117+
{
118+
value = default;
119+
return false;
120+
}
121+
122+
key = node;
137123
node = key.next;
138124
}
139125

140-
if (!node.HasValue)
141-
{
142-
value = default;
143-
return false;
126+
if (key.hasValue)
127+
{
128+
value = key.value;
129+
return true;
130+
}
131+
else
132+
{
133+
value = default;
134+
return false;
144135
}
145-
146-
value = node.Value;
147-
return true;
148136
}
149137

150138
public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
Lines changed: 97 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,97 @@
1-
/*----------------------------------------------------------
2-
This Source Code Form is subject to the terms of the
3-
Mozilla Public License, v.2.0. If a copy of the MPL
4-
was not distributed with this file, You can obtain one
5-
at http://mozilla.org/MPL/2.0/.
6-
----------------------------------------------------------*/
7-
8-
using System.Text;
9-
10-
namespace OneScript.Language.LexicalAnalysis
11-
{
12-
public class StringLexerState : LexerState
13-
{
14-
private void SkipSpacesAndComments(SourceCodeIterator iterator)
15-
{
16-
while (true)
17-
{ /* Пропускаем все пробелы и комментарии */
18-
iterator.SkipSpaces();
19-
20-
if (iterator.CurrentSymbol == '/')
21-
{
22-
if (!iterator.MoveNext())
23-
throw CreateExceptionOnCurrentLine("Некорректный символ", iterator);
24-
25-
if (iterator.CurrentSymbol != '/')
26-
throw CreateExceptionOnCurrentLine("Некорректный символ", iterator);
27-
28-
do
29-
{
30-
if (!iterator.MoveNext())
31-
break;
32-
33-
} while (iterator.CurrentSymbol != '\n');
34-
35-
}
36-
else
37-
break;
38-
}
39-
}
40-
41-
public override Lexem ReadNextLexem(SourceCodeIterator iterator)
42-
{
43-
StringBuilder contentBuilder = new StringBuilder();
44-
45-
while (iterator.MoveNext())
46-
{
47-
var cs = iterator.CurrentSymbol;
48-
49-
if (cs == SpecialChars.StringQuote)
50-
{
51-
if (iterator.MoveNext())
52-
{
53-
if (iterator.CurrentSymbol == SpecialChars.StringQuote)
54-
{
55-
/* Двойная кавычка */
56-
contentBuilder.Append("\"");
57-
continue;
58-
}
59-
60-
/* Завершение строки */
61-
SkipSpacesAndComments(iterator);
62-
63-
if (iterator.CurrentSymbol == SpecialChars.StringQuote)
64-
{
65-
/* Сразу же началась новая строка */
66-
contentBuilder.Append('\n');
67-
continue;
68-
}
69-
}
70-
71-
var lex = new Lexem
72-
{
73-
Type = LexemType.StringLiteral,
74-
Content = contentBuilder.ToString()
75-
};
76-
return lex;
77-
}
78-
79-
if (cs == '\n')
80-
{
81-
iterator.MoveNext();
82-
SkipSpacesAndComments(iterator);
83-
84-
if (iterator.CurrentSymbol != '|')
85-
throw CreateExceptionOnCurrentLine("Некорректный строковый литерал!", iterator);
86-
87-
contentBuilder.Append('\n');
88-
}
89-
else if(cs != '\r')
90-
contentBuilder.Append(cs);
91-
92-
}
93-
94-
throw CreateExceptionOnCurrentLine("Незавершённый строковой интервал!", iterator);
95-
}
96-
}
97-
}
1+
/*----------------------------------------------------------
2+
This Source Code Form is subject to the terms of the
3+
Mozilla Public License, v.2.0. If a copy of the MPL
4+
was not distributed with this file, You can obtain one
5+
at http://mozilla.org/MPL/2.0/.
6+
----------------------------------------------------------*/
7+
8+
using System.Text;
9+
10+
namespace OneScript.Language.LexicalAnalysis
11+
{
12+
public class StringLexerState : LexerState
13+
{
14+
private void SkipSpacesAndComments(SourceCodeIterator iterator)
15+
{
16+
while (true)
17+
{ /* Пропускаем все пробелы и комментарии */
18+
iterator.SkipSpaces();
19+
20+
if (iterator.CurrentSymbol == '/')
21+
{
22+
if (!iterator.MoveNext())
23+
throw CreateExceptionOnCurrentLine("Некорректный символ", iterator);
24+
25+
if (iterator.CurrentSymbol != '/')
26+
throw CreateExceptionOnCurrentLine("Некорректный символ", iterator);
27+
28+
do
29+
{
30+
if (!iterator.MoveNext())
31+
break;
32+
33+
} while (iterator.CurrentSymbol != '\n');
34+
35+
}
36+
else
37+
break;
38+
}
39+
}
40+
41+
public override Lexem ReadNextLexem(SourceCodeIterator iterator)
42+
{
43+
StringBuilder contentBuilder = new StringBuilder();
44+
45+
while (iterator.MoveNext())
46+
{
47+
var cs = iterator.CurrentSymbol;
48+
49+
if (cs == SpecialChars.StringQuote)
50+
{
51+
if (iterator.MoveNext())
52+
{
53+
if (iterator.CurrentSymbol == SpecialChars.StringQuote)
54+
{
55+
/* Двойная кавычка */
56+
contentBuilder.Append("\"");
57+
continue;
58+
}
59+
60+
/* Завершение строки */
61+
SkipSpacesAndComments(iterator);
62+
63+
if (iterator.CurrentSymbol == SpecialChars.StringQuote)
64+
{
65+
/* Сразу же началась новая строка */
66+
contentBuilder.Append('\n');
67+
continue;
68+
}
69+
}
70+
71+
var lex = new Lexem
72+
{
73+
Type = LexemType.StringLiteral,
74+
Content = contentBuilder.ToString()
75+
};
76+
return lex;
77+
}
78+
79+
if (cs == '\n')
80+
{
81+
iterator.MoveNext();
82+
SkipSpacesAndComments(iterator);
83+
84+
if (iterator.CurrentSymbol != '|')
85+
throw CreateExceptionOnCurrentLine("Некорректный строковый литерал!", iterator);
86+
87+
contentBuilder.Append('\n');
88+
}
89+
else if(cs != '\r')
90+
contentBuilder.Append(cs);
91+
92+
}
93+
94+
throw CreateExceptionOnCurrentLine("Незавершённый строковый литерал!", iterator);
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)