@@ -379,24 +379,26 @@ class Trie {
379
379
public:
380
380
Trie (const std::vector<std::string> &items, bool ignore_case)
381
381
: ignore_case_(ignore_case) {
382
+ size_t id = 0 ;
382
383
for (const auto &item : items) {
383
384
for (size_t len = 1 ; len <= item.size (); len++) {
384
385
auto last = len == item.size ();
385
386
const auto &s = ignore_case ? to_lower (item) : item;
386
387
std::string_view sv (s.data (), len);
387
388
auto it = dic_.find (sv);
388
389
if (it == dic_.end ()) {
389
- dic_.emplace (sv, Info{last, last});
390
+ dic_.emplace (sv, Info{last, last, id });
390
391
} else if (last) {
391
392
it->second .match = true ;
392
393
} else {
393
394
it->second .done = false ;
394
395
}
395
396
}
397
+ id++;
396
398
}
397
399
}
398
400
399
- size_t match (const char *text, size_t text_len) const {
401
+ size_t match (const char *text, size_t text_len, size_t &id ) const {
400
402
size_t match_len = 0 ;
401
403
auto done = false ;
402
404
size_t len = 1 ;
@@ -407,14 +409,19 @@ class Trie {
407
409
if (it == dic_.end ()) {
408
410
done = true ;
409
411
} else {
410
- if (it->second .match ) { match_len = len; }
412
+ if (it->second .match ) {
413
+ match_len = len;
414
+ id = it->second .id ;
415
+ }
411
416
if (it->second .done ) { done = true ; }
412
417
}
413
418
len += 1 ;
414
419
}
415
420
return match_len;
416
421
}
417
422
423
+ size_t size () const { return dic_.size (); }
424
+
418
425
private:
419
426
std::string to_lower (std::string s) const {
420
427
for (char &c : s) {
@@ -426,6 +433,7 @@ class Trie {
426
433
struct Info {
427
434
bool done;
428
435
bool match;
436
+ size_t id;
429
437
};
430
438
431
439
// TODO: Use unordered_map when heterogeneous lookup is supported in C++20
@@ -580,6 +588,7 @@ struct SemanticValues : protected std::vector<std::any> {
580
588
581
589
private:
582
590
friend class Context ;
591
+ friend class Dictionary ;
583
592
friend class Sequence ;
584
593
friend class PrioritizedChoice ;
585
594
friend class Repetition ;
@@ -2673,12 +2682,17 @@ inline size_t Ope::parse(const char *s, size_t n, SemanticValues &vs,
2673
2682
inline size_t Dictionary::parse_core (const char *s, size_t n,
2674
2683
SemanticValues &vs, Context &c,
2675
2684
std::any &dt) const {
2676
- auto i = trie_.match (s, n);
2685
+ size_t id;
2686
+ auto i = trie_.match (s, n, id);
2687
+
2677
2688
if (i == 0 ) {
2678
2689
c.set_error_pos (s);
2679
2690
return static_cast <size_t >(-1 );
2680
2691
}
2681
2692
2693
+ vs.choice_count_ = trie_.size ();
2694
+ vs.choice_ = id;
2695
+
2682
2696
// Word check
2683
2697
if (c.wordOpe ) {
2684
2698
auto save_ignore_trace_state = c.ignore_trace_state ;
@@ -2792,7 +2806,8 @@ inline size_t Holder::parse_core(const char *s, size_t n, SemanticValues &vs,
2792
2806
auto tok_ptr = dynamic_cast <const peg::TokenBoundary *>(ope_ptr);
2793
2807
if (tok_ptr) { ope_ptr = tok_ptr->ope_ .get (); }
2794
2808
}
2795
- if (!dynamic_cast <const peg::PrioritizedChoice *>(ope_ptr)) {
2809
+ if (!dynamic_cast <const peg::PrioritizedChoice *>(ope_ptr) &&
2810
+ !dynamic_cast <const peg::Dictionary *>(ope_ptr)) {
2796
2811
chvs.choice_count_ = 0 ;
2797
2812
chvs.choice_ = 0 ;
2798
2813
}
0 commit comments