@@ -377,14 +377,13 @@ template <typename T> T token_to_number_(std::string_view sv) {
377
377
378
378
class Trie {
379
379
public:
380
- Trie () = default ;
381
- Trie (const Trie &) = default ;
382
-
383
- Trie (const std::vector<std::string> &items) {
380
+ Trie (const std::vector<std::string> &items, bool ignore_case)
381
+ : ignore_case_(ignore_case) {
384
382
for (const auto &item : items) {
385
383
for (size_t len = 1 ; len <= item.size (); len++) {
386
384
auto last = len == item.size ();
387
- std::string_view sv (item.data (), len);
385
+ const auto &s = ignore_case ? to_lower (item) : item;
386
+ std::string_view sv (s.data (), len);
388
387
auto it = dic_.find (sv);
389
388
if (it == dic_.end ()) {
390
389
dic_.emplace (sv, Info{last, last});
@@ -402,7 +401,8 @@ class Trie {
402
401
auto done = false ;
403
402
size_t len = 1 ;
404
403
while (!done && len <= text_len) {
405
- std::string_view sv (text, len);
404
+ const auto &s = ignore_case_ ? to_lower (text) : std::string (text);
405
+ std::string_view sv (s.data (), len);
406
406
auto it = dic_.find (sv);
407
407
if (it == dic_.end ()) {
408
408
done = true ;
@@ -416,6 +416,13 @@ class Trie {
416
416
}
417
417
418
418
private:
419
+ std::string to_lower (std::string s) const {
420
+ for (char &c : s) {
421
+ c = std::tolower (c);
422
+ }
423
+ return s;
424
+ }
425
+
419
426
struct Info {
420
427
bool done;
421
428
bool match;
@@ -424,6 +431,8 @@ class Trie {
424
431
// TODO: Use unordered_map when heterogeneous lookup is supported in C++20
425
432
// std::unordered_map<std::string, Info> dic_;
426
433
std::map<std::string, Info, std::less<>> dic_;
434
+
435
+ bool ignore_case_;
427
436
};
428
437
429
438
/* -----------------------------------------------------------------------------
@@ -1159,7 +1168,8 @@ class NotPredicate : public Ope {
1159
1168
1160
1169
class Dictionary : public Ope , public std ::enable_shared_from_this<Dictionary> {
1161
1170
public:
1162
- Dictionary (const std::vector<std::string> &v) : trie_(v) {}
1171
+ Dictionary (const std::vector<std::string> &v, bool ignore_case)
1172
+ : trie_(v, ignore_case) {}
1163
1173
1164
1174
size_t parse_core (const char *s, size_t n, SemanticValues &vs, Context &c,
1165
1175
std::any &dt) const override ;
@@ -1568,8 +1578,9 @@ inline std::shared_ptr<Ope> npd(const std::shared_ptr<Ope> &ope) {
1568
1578
return std::make_shared<NotPredicate>(ope);
1569
1579
}
1570
1580
1571
- inline std::shared_ptr<Ope> dic (const std::vector<std::string> &v) {
1572
- return std::make_shared<Dictionary>(v);
1581
+ inline std::shared_ptr<Ope> dic (const std::vector<std::string> &v,
1582
+ bool ignore_case) {
1583
+ return std::make_shared<Dictionary>(v, ignore_case);
1573
1584
}
1574
1585
1575
1586
inline std::shared_ptr<Ope> lit (std::string &&s) {
@@ -3335,16 +3346,17 @@ class ParserGenerator {
3335
3346
seq (g[" Suffix" ], opt (seq (g[" LABEL" ], g[" Identifier" ])));
3336
3347
g[" Suffix" ] <= seq (g[" Primary" ], opt (g[" Loop" ]));
3337
3348
g[" Loop" ] <= cho (g[" QUESTION" ], g[" STAR" ], g[" PLUS" ], g[" Repetition" ]);
3338
- g[" Primary" ] <=
3339
- cho (seq (g[" Ignore" ], g[" IdentCont" ], g[" Arguments" ],
3340
- npd (g[" LEFTARROW" ])),
3341
- seq (g[" Ignore" ], g[" Identifier" ],
3342
- npd (seq (opt (g[" Parameters" ]), g[" LEFTARROW" ]))),
3343
- seq (g[" OPEN" ], g[" Expression" ], g[" CLOSE" ]),
3344
- seq (g[" BeginTok" ], g[" Expression" ], g[" EndTok" ]), g[" CapScope" ],
3345
- seq (g[" BeginCap" ], g[" Expression" ], g[" EndCap" ]), g[" BackRef" ],
3346
- g[" LiteralI" ], g[" Dictionary" ], g[" Literal" ], g[" NegatedClassI" ],
3347
- g[" NegatedClass" ], g[" ClassI" ], g[" Class" ], g[" DOT" ]);
3349
+ g[" Primary" ] <= cho (seq (g[" Ignore" ], g[" IdentCont" ], g[" Arguments" ],
3350
+ npd (g[" LEFTARROW" ])),
3351
+ seq (g[" Ignore" ], g[" Identifier" ],
3352
+ npd (seq (opt (g[" Parameters" ]), g[" LEFTARROW" ]))),
3353
+ seq (g[" OPEN" ], g[" Expression" ], g[" CLOSE" ]),
3354
+ seq (g[" BeginTok" ], g[" Expression" ], g[" EndTok" ]),
3355
+ g[" CapScope" ],
3356
+ seq (g[" BeginCap" ], g[" Expression" ], g[" EndCap" ]),
3357
+ g[" BackRef" ], g[" DictionaryI" ], g[" LiteralI" ],
3358
+ g[" Dictionary" ], g[" Literal" ], g[" NegatedClassI" ],
3359
+ g[" NegatedClass" ], g[" ClassI" ], g[" Class" ], g[" DOT" ]);
3348
3360
3349
3361
g[" Identifier" ] <= seq (g[" IdentCont" ], g[" Spacing" ]);
3350
3362
g[" IdentCont" ] <= tok (seq (g[" IdentStart" ], zom (g[" IdentRest" ])));
@@ -3358,18 +3370,23 @@ class ParserGenerator {
3358
3370
3359
3371
g[" Dictionary" ] <= seq (g[" LiteralD" ], oom (seq (g[" PIPE" ], g[" LiteralD" ])));
3360
3372
3373
+ g[" DictionaryI" ] <=
3374
+ seq (g[" LiteralID" ], oom (seq (g[" PIPE" ], g[" LiteralID" ])));
3375
+
3361
3376
auto lit_ope = cho (seq (cls (" '" ), tok (zom (seq (npd (cls (" '" )), g[" Char" ]))),
3362
3377
cls (" '" ), g[" Spacing" ]),
3363
3378
seq (cls (" \" " ), tok (zom (seq (npd (cls (" \" " )), g[" Char" ]))),
3364
3379
cls (" \" " ), g[" Spacing" ]));
3365
3380
g[" Literal" ] <= lit_ope;
3366
3381
g[" LiteralD" ] <= lit_ope;
3367
3382
3368
- g[ " LiteralI " ] < =
3383
+ auto lit_case_ignore_ope =
3369
3384
cho (seq (cls (" '" ), tok (zom (seq (npd (cls (" '" )), g[" Char" ]))), lit (" 'i" ),
3370
3385
g[" Spacing" ]),
3371
3386
seq (cls (" \" " ), tok (zom (seq (npd (cls (" \" " )), g[" Char" ]))), lit (" \" i" ),
3372
3387
g[" Spacing" ]));
3388
+ g[" LiteralI" ] <= lit_case_ignore_ope;
3389
+ g[" LiteralID" ] <= lit_case_ignore_ope;
3373
3390
3374
3391
// NOTE: The original Brian Ford's paper uses 'zom' instead of 'oom'.
3375
3392
g[" Class" ] <= seq (chr (' [' ), npd (chr (' ^' )),
@@ -3720,7 +3737,11 @@ class ParserGenerator {
3720
3737
3721
3738
g[" Dictionary" ] = [](const SemanticValues &vs) {
3722
3739
auto items = vs.transform <std::string>();
3723
- return dic (items);
3740
+ return dic (items, false );
3741
+ };
3742
+ g[" DictionaryI" ] = [](const SemanticValues &vs) {
3743
+ auto items = vs.transform <std::string>();
3744
+ return dic (items, true );
3724
3745
};
3725
3746
3726
3747
g[" Literal" ] = [](const SemanticValues &vs) {
@@ -3735,6 +3756,10 @@ class ParserGenerator {
3735
3756
auto &tok = vs.tokens .front ();
3736
3757
return resolve_escape_sequence (tok.data (), tok.size ());
3737
3758
};
3759
+ g[" LiteralID" ] = [](const SemanticValues &vs) {
3760
+ auto &tok = vs.tokens .front ();
3761
+ return resolve_escape_sequence (tok.data (), tok.size ());
3762
+ };
3738
3763
3739
3764
g[" Class" ] = [](const SemanticValues &vs) {
3740
3765
auto ranges = vs.transform <std::pair<char32_t , char32_t >>();
0 commit comments