| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "ParserPch.h"
- namespace UnifiedRegex
- {
- // ----------------------------------------------------------------------
- // CharTrie
- // ----------------------------------------------------------------------
- __inline bool CharTrie::Find(Char c, int& outi)
- {
- if (count == 0)
- {
- outi = 0;
- return false;
- }
- int l = 0;
- int h = count - 1;
- while (true)
- {
- int m = (l + h) / 2;
- if (children[m].c == c)
- {
- outi = m;
- return true;
- }
- else if (CTU(children[m].c) < CTU(c))
- {
- l = m + 1;
- if (l > h)
- {
- outi = l;
- return false;
- }
- }
- else
- {
- h = m - 1;
- if (h < l)
- {
- outi = m;
- return false;
- }
- }
- }
- return false;
- }
- void CharTrie::FreeBody(ArenaAllocator* allocator)
- {
- for (int i = 0; i < count; i++)
- children[i].node.FreeBody(allocator);
- if (capacity > 0)
- AdeleteArray(allocator, capacity, children);
- #if DBG
- count = 0;
- capacity = 0;
- children = 0;
- #endif
- }
- CharTrie* CharTrie::Add(ArenaAllocator* allocator, Char c)
- {
- int i;
- if (!Find(c, i))
- {
- if (capacity <= count)
- {
- int newCapacity = max(capacity * 2, initCapacity);
- children = (CharTrieEntry*)allocator->Realloc(children, capacity * sizeof(CharTrieEntry), newCapacity * sizeof(CharTrieEntry));
- capacity = newCapacity;
- }
- for (int j = count; j > i; j--)
- {
- children[j].c = children[j - 1].c;
- children[j].node = children[j - 1].node;
- }
- children[i].c = c;
- children[i].node.Reset();
- count++;
- }
- return &children[i].node;
- }
- bool CharTrie::IsDepthZero() const
- {
- return isAccepting && count == 0;
- }
- bool CharTrie::IsDepthOne() const
- {
- if (isAccepting)
- return 0;
- for (int i = 0; i < count; i++)
- {
- if (!children[i].node.IsDepthZero())
- return false;
- }
- return true;
- }
- #if ENABLE_REGEX_CONFIG_OPTIONS
- void CharTrie::Print(DebugWriter* w) const
- {
- w->Indent();
- if (isAccepting)
- w->PrintEOL(_u("<accept>"));
- for (int i = 0; i < count; i++)
- {
- w->PrintQuotedChar(children[i].c);
- w->EOL();
- children[i].node.Print(w);
- }
- w->Unindent();
- }
- #endif
- // ----------------------------------------------------------------------
- // RuntimeCharTrie
- // ----------------------------------------------------------------------
- bool RuntimeCharTrie::Match
- (const Char* const input
- , const CharCount inputLength
- , CharCount& inputOffset
- #if ENABLE_REGEX_CONFIG_OPTIONS
- , RegexStats* stats
- #endif
- ) const
- {
- const RuntimeCharTrie* curr = this;
- while (true)
- {
- if (curr->count == 0)
- return true;
- if (inputOffset >= inputLength)
- return false;
- #if ENABLE_REGEX_CONFIG_OPTIONS
- if (stats != 0)
- stats->numCompares++;
- #endif
- #if 0
- int l = 0;
- int h = curr->count - 1;
- while (true)
- {
- if (l > h)
- return false;
- int m = (l + h) / 2;
- if (curr->children[m].c == input[inputOffset])
- {
- inputOffset++;
- curr = &curr->children[m].node;
- break;
- }
- else if (CTU(curr->children[m].c) < CTU(input[inputOffset]))
- l = m + 1;
- else
- h = m - 1;
- }
- #else
- int i = 0;
- while (true)
- {
- if (curr->children[i].c == input[inputOffset])
- {
- inputOffset++;
- curr = &curr->children[i].node;
- break;
- }
- else if (curr->children[i].c > input[inputOffset])
- return false;
- else if (++i >= curr->count)
- return false;
- }
- #endif
- }
- }
- void RuntimeCharTrie::FreeBody(ArenaAllocator* allocator)
- {
- for (int i = 0; i < count; i++)
- children[i].node.FreeBody(allocator);
- if (count > 0)
- AdeleteArray(allocator, count, children);
- #if DBG
- count = 0;
- children = 0;
- #endif
- }
- void RuntimeCharTrie::CloneFrom(ArenaAllocator* allocator, const CharTrie& other)
- {
- count = other.count;
- if (count > 0)
- {
- children = AnewArray(allocator, RuntimeCharTrieEntry, count);
- for (int i = 0; i < count; i++)
- {
- children[i].c = other.children[i].c;
- children[i].node.CloneFrom(allocator, other.children[i].node);
- }
- }
- else
- children = 0;
- }
- #if ENABLE_REGEX_CONFIG_OPTIONS
- void RuntimeCharTrie::Print(DebugWriter* w) const
- {
- w->Indent();
- for (int i = 0; i < count; i++)
- {
- w->PrintQuotedChar(children[i].c);
- w->EOL();
- children[i].node.Print(w);
- }
- w->Unindent();
- }
- #endif
- }
|