ShoshinX / RustRegexEngine

A cache friendly implementation of regex in rust using Thompson's NFA method

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

maybe need something like dual pointer.

Opadc opened this issue · comments

commented

hi, I'm trying follow the Russ Cox regex blog in Rust.
And inspired by your implement which use Vec to simulate LinkList with StateIndex.
Finally I run into same trouble, code is not work.
After longtime review C code, I realize single StateIndex is not enough.
In the Frag struct, hold a pointer to Ptrlist, the latter is hold a pointer to State or next pointer to next Ptrlist.
So out field in Frag is just list of pointer which point to State.

struct Frag
{
	State *start;
	Ptrlist *out;
};
union Ptrlist
{
	Ptrlist *next;
	State *s;
};

So far so good. except function list1(), which take a dual pointer to State and coercion to pointer to Ptrlist.

Ptrlist*
list1(State **outp)
{
	Ptrlist *l;
	
	l = (Ptrlist*)outp;
	l->next = NULL;
	return l;
}

The key point is the argument when calling list1(), which is pointer to out field of State s, but out filed in State is just pointer to another State.
So after construct frag with list1(&s->out), the out field in frag contain a dual pointer to out field in State s, rather a pointer to State s self.

push(frag(s, list1(&s->out)));

I am not a native English speaker and not good at talk, this is my StateIndex to simulate dual pointer

enum StateIndex {
    Index(usize),
    DualIndex2out(usize), // use DualIndex2out simluate double pointer. modify DualIndex2out(2) equal modify state.out which state = states[2];
    DualIndex2out1(usize), // modify DualIndex2out1(2) equal modify state.out1 which state = states[2];
}

and how it impact patch() which add arrows between states.

fn patch(&mut self, state_index: StateIndex, states: &mut Slab<State>) {
        for index in &self.out {
            match index {
                StateIndex::Index(index) => {
                    let state = states.get_mut(*index).unwrap();
                    state.out = state_index;
                }
                StateIndex::DualIndex2out(doul_index) => {
                    let state = states.get_mut(*doul_index).unwrap();
                    state.out = state_index;
                }
                StateIndex::DualIndex2out1(doul_index) => {
                    let state = states.get_mut(*doul_index).unwrap();
                    state.out1 = state_index;
                }
            }
        }
    }

lastly, this is my implement, which almost steal from you, thx.