1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

token: fix a new_keywords_matcher_from_array_trie bug (first word with idx 0 was ignored); add tests

This commit is contained in:
Delyan Angelov 2022-07-29 22:58:43 +03:00
parent a42eb3b947
commit 2db8bd62a2
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 27 additions and 8 deletions

View File

@ -5,7 +5,7 @@ module token
// See the module description for more details.
[heap]
pub struct KeywordsMatcherTrie {
mut:
pub mut:
nodes []&TrieNode
min_len int = 999999
max_len int
@ -13,9 +13,9 @@ mut:
// TrieNode is a single node from a trie, used by KeywordsMatcherTrie
pub struct TrieNode {
mut:
pub mut:
children [123]&TrieNode
value int // when positive, it is a leaf node representing a match
value int = -1 // when != -1, it is a leaf node representing a match
}
// find tries to find the given `word` in the set of all previously added words
@ -38,6 +38,11 @@ pub fn (km &KeywordsMatcherTrie) find(word string) int {
return node.find(word)
}
[inline]
pub fn (km &KeywordsMatcherTrie) matches(word string) bool {
return km.find(word) != -1
}
// add_word adds the given word to the KeywordsMatcherTrie instance. It associates a non
// negative integer value to it, so later `find` could return the value, when it succeeds.
[direct_array_access]
@ -92,13 +97,14 @@ pub fn new_trie_node() &TrieNode {
// show displays the information in `node`, in a more compact/readable format (recursively)
pub fn (node &TrieNode) show(level int) {
mut non_nil_children := 0
for x in node.children {
mut non_nil_children := []int{}
for idx, x in node.children {
if x != unsafe { nil } {
non_nil_children++
non_nil_children << idx
}
}
eprintln('> level: ${level:2} | value: ${node.value:12} | non_nil_children: ${non_nil_children:2}')
children := non_nil_children.map(u8(it).ascii_str())
eprintln('> level: ${level:2} | value: ${node.value:12} | non_nil_children: ${non_nil_children.len:2} | $children')
for x in node.children {
if x != unsafe { nil } {
x.show(level + 1)
@ -134,7 +140,7 @@ pub fn (root &TrieNode) find(word string) int {
// eprintln('> match_keyword: `${word:20}` | node: ${ptr_str(node)} | idx: ${idx:3}')
if idx == wlen {
k := node.value
if k > 0 {
if k != -1 {
// node.show(0)
return k
}

View File

@ -0,0 +1,13 @@
import v.token
fn test_new_keywords_matcher_from_array_trie_works() {
method_names := ['filter', 'clone', 'repeat', 'reverse', 'map', 'slice', 'sort', 'contains',
'index', 'wait', 'any', 'all', 'first', 'last', 'pop']
matcher := token.new_keywords_matcher_from_array_trie(method_names)
for word in [method_names.first(), method_names.last(), 'something', 'another', 'x', 'y', '',
'---', '123', 'abc.def', 'xyz !@#'] {
res1 := matcher.find(word) != -1
res2 := word in method_names
assert res1 == res2
}
}