Exemple #1
0
int is_match_pike(struct Prog* prog,char* input, char** subp) {
  char* sp;
  struct Sub* sub;
  struct Inst* pc;
  int matched = 0;
  struct ThreadList *clist, *nlist, *tlist;
  int len = prog->len;
  clist = threadlist(len);
  nlist = threadlist(len);
  gen++;
  sub = newsub();
  int i;
  for(i = 0; i < MAXSUB; i++)
    sub->sub[i] = NULL;
  addthread(clist, thread(prog->start, sub), input);
  for(sp = input; ; sp++) {
    if(clist->n == 0)
      break;
    gen++;
    for(i = 0; i < clist->n; i++) {
      pc = clist->t[i].pc;
      sub = clist->t[i].sub;
      switch(pc->opcode) {
        case Char:
          if(*sp != pc->c) {
            decref(sub);
	    break;
	  }
          //printf("%c", pc->c);
	case Any:
	  if(*sp == '\0') {
	    decref(sub);
	    break;
	  }
          addthread(nlist, thread(pc+1, sub), sp+1);
          break;
        case Match:
          matched = 1;
	  int i;
	  for(i = 0; i < MAXSUB; i++)
	    subp[i] = sub->sub[i];
          for(i = 0; i < clist->n; i++)
	    decref(clist->t[i].sub);
	  goto BreakFor;
       }
     }
    //printf("\n");
    BreakFor:
             tlist = clist;
	     clist = nlist;
	     nlist = tlist;
	     nlist->n = 0;
	     if(sp == '\0')
	       break;
  }
  if(matched)
    return sp - input;
            return 0;
}
Exemple #2
0
Sub*
update(Sub *s, int i, const char *p)
{
	Sub *s1;
	int j;

	if(s->ref > 1) {
		s1 = newsub(s->nsub);
		for(j=0; j<s->nsub; j++)
			s1->sub[j] = s->sub[j];
		s->ref--;
		s = s1;
	}
	s->sub[i] = p;
	return s;
}
Exemple #3
0
static void test_add_thread(void) {
  char input[] = "ab";
  struct Regexp* re = parse(input);
  struct Prog* prog = compile(re);
  struct Inst* pc = prog->start;
  struct Sub* s = newsub();
  struct ThreadList* list = threadlist(2);
  gen++;
  addthread(list, thread(pc, s), input);
  gen++;
  addthread(list, thread(pc+1, s), input);
  assert('a' == list->t[0].pc->c);
  assert(Char == list->t[0].pc->opcode);
  assert('b' == list->t[1].pc->c);
  assert(Char == list->t[0].pc->opcode);
}
Exemple #4
0
int
backtrack(Prog *prog, char *input, char **subp, int nsubp)
{
	enum { MAX = 1000 };
	Thread ready[MAX];
	int i, nready;
	Inst *pc;
	char *sp;
	Sub *sub;

	/* queue initial thread */
	sub = newsub(nsubp);
	for(i=0; i<nsubp; i++)
		sub->sub[i] = nil;
	ready[0] = thread(prog->start, input, sub);
	nready = 1;

	/* run threads in stack order */
	while(nready > 0) {
		--nready;	/* pop state for next thread to run */
		pc = ready[nready].pc;
		sp = ready[nready].sp;
		sub = ready[nready].sub;
		assert(sub->ref > 0);
		for(;;) {
			switch(pc->opcode) {
			case Char:
				if(*sp != pc->c)
					goto Dead;
				pc++;
				sp++;
				continue;
			case Any:
				if(*sp == 0)
					goto Dead;
				pc++;
				sp++;
				continue;
			case Match:
				for(i=0; i<nsubp; i++)
					subp[i] = sub->sub[i];
				decref(sub);
				return 1;
			case Jmp:
				pc = pc->x;
				continue;
			case Split:
				if(nready >= MAX)
					fatal("backtrack overflow");
				ready[nready++] = thread(pc->y, sp, incref(sub));
				pc = pc->x;	/* continue current thread */
				continue;
			case Save:
				sub = update(sub, pc->n, sp);
				pc++;
				continue;
			}
		}
	Dead:
		decref(sub);
	}
	return 0;
}