示例#1
0
    inline bool st_search(StateParser & stparser, const char * s)
    {
        if ( stparser.empty()) {
            return false;
        }

        StatesValue stval(stparser.states(), stparser.nb_capture());

// #ifdef DISPLAY_TRACE
//         display_states(stval, stparser.root());
// #endif

        st_step_range_list_t lst;
        st_step_range_list_t l1;
        add_first(lst, l1, stparser.root());
        if (l1.empty() && lst.empty()) {
            return false;
        }
        utf8_consumer consumer(s);
        st_step_range_list_t l2;
        bool res = false;
        unsigned count = 1;
        while (consumer.valid()) {
#ifdef DISPLAY_TRACE
            std::cout << "\033[01;31mc: '" << utf8_char(consumer.getc()) << "'\033[0m\n";
#endif
            for (st_step_range_iterator_t first = lst.begin(), last = lst.end(); first != last; ++first) {
                if (stval.get_num_at(first->first) != count) {
                    l1.push_back(*first);
                }
            }
            if (l1.empty()) {
                return false;
            }
            l2.clear();
            if ((res = st_step(l1, l2, stval, consumer.bumpc(), consumer, ++count))) {
                break ;
            }
            l1.swap(l2);
        }
        if (res) {
            return true;
        }
        if (consumer.valid()) {
            return false;
        }
        for (st_step_range_iterator_t first = l1.begin(), last = l1.end(); first != last; ++first) {
            if (first->first->type == LAST) {
                return true;
            }
        }
        return false;
    }
示例#2
0
 unsigned contains(char_int c, utf8_consumer consumer) const {
     if (c == this->s[0]) {
         const char_int * s = this->s + 1;
         while (*s && *s == consumer.bumpc()) {
             ++s;
         }
         return *s ? 0 : s - this->s;
     }
     return 0;
 }
    inline bool st_exact_search(StateParser & stparser, const char * s)
    {
        if ( stparser.empty() ) {
            return false;
        }

        StatesValue stval(stparser.states(), stparser.nb_capture());

// #ifdef DISPLAY_TRACE
//         display_states(stval, stparser.root());
// #endif

        st_step_range_list_t l1;
        add_first(l1, l1, stparser.root());
        if (l1.empty()) {
            return false;
        }
        utf8_consumer consumer(s);
        st_step_range_list_t l2;
        bool res = false;
        unsigned count = 1;
        while (consumer.valid() && !(res = st_exact_step(l1, l2, stval, consumer.bumpc(), consumer, ++count))) {
#ifdef DISPLAY_TRACE
            std::cout << "\033[01;31mc: '" << utf8_char(consumer.getc()) << "'\033[0m\n";
#endif
            if (l2.empty()) {
                return false;
            }
            l1.swap(l2);
            l2.clear();
        }

        if (consumer.valid()) {
            return false;
        }
        if (res) {
            return true;
        }
        return false;
    }
示例#4
0
    inline bool st_exact_step(st_step_range_list_t & l1, st_step_range_list_t & l2,
                              StatesValue & stval, size_t c, utf8_consumer & consumer, unsigned count)
    {
        struct add {
            static bool impl(st_step_range_list_t & l, const State * st,
                             StatesValue & stval, bool is_end, unsigned count, unsigned count_consume)
            {
                if (stval.get_num_at(st) == count) {
                    return false;
                }
                stval.set_num_at(st, count);
                if (st->is_split()) {
                    if (st->out1 && impl(l, st->out1, stval, is_end, count, count_consume)) {
                        return true;
                    }
                    if (st->out2 && impl(l, st->out2, stval, is_end, count, count_consume)) {
                        return true;
                    }
                }
                else if (st->is_cap()) {
                    if (st->out1) {
                        return impl(l, st->out1, stval, is_end, count, count_consume);
                    }
                }
                else if (st) {
                    if (st->is_terminate()) {
                        if (count_consume > 0) {
                            l.push_back(st_step_elem_t(st, count_consume));
                        }
                        else if (is_end) {
                            return true;
                        }
                    }
                    else {
                        l.push_back(st_step_elem_t(st, count_consume));
                    }
                }
                return false;
            }

            static bool push_next(st_step_range_list_t & l, const State * st,
                                  StatesValue & stval, bool is_end, unsigned count)
            {
                if ( ! st->out1 && ! st->out2 && is_end) {
                    return true;
                }
                if (st->out1 && impl(l, st->out1, stval, is_end, count, 0)) {
                    return true;
                }
                if (st->out2 && impl(l, st->out2, stval, is_end, count, 0)) {
                    return true;
                }
                return false;
            }
        };

        const bool is_end = ! consumer.valid();
        unsigned r;
        for (st_step_range_iterator_t first = l1.begin(), last = l1.end(); first != last; ++first) {
#ifdef DISPLAY_TRACE
            std::cout << (*first->first) << std::endl;
#endif
            if (first->second) {
#ifdef DISPLAY_TRACE
                std::cout << "continue " << first->second << std::endl;
#endif
                if (!--first->second) {
                    if (add::push_next(l2, first->first, stval, is_end, count)) {
                        return true;
                    }
                }
                else {
                    l2.push_back(*first);
                }
                continue;
            }
            if ( ! first->first->is_cap() && (r = first->first->check(c, consumer))) {
#ifdef DISPLAY_TRACE
                std::cout << "ok" << std::endl;
#endif
                if (r != 1) {
                    l2.push_back(st_step_elem_t(first->first, r-1));
                }
                else if (add::push_next(l2, first->first, stval, is_end, count)) {
                    return true;
                }
            }
        }
        return false;
    }