-
Notifications
You must be signed in to change notification settings - Fork 0
/
patternMatching1.cpp
75 lines (69 loc) · 1.77 KB
/
patternMatching1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
enum patternType{all,any};
Aggregate allPos(Aggregate s){
uWord sn=s.elements();Aggregate r(sn,sn);
for(uWord i=0;i<s.elements();i++) r[i]=i;
return r;
}
AggregateOrdered matchEnd(Aggregate s,AggregateOrdered positions){
AggregateOrdered r;
if(positions.keyExists(s.elements(),false))
r.push(s.elements());
return r;
}
AggregateOrdered match(const Aggregate s,AggregateOrdered positions, Obj pat,AggregateOrdered r=0,Word pn=1){
// p holds the positions array that may have 1 or 2 columns per raw
#define loop(aa,step) for(Word i=0,i1=aa.elements(),p;i<i1 && (p=aa[i],true);i+=step)
switch(pat.Class().w){
case _classInt:{
if(!r)
r=AggregateOrdered();
uWord sn=s.elements();
loop(positions,pn){
if(0<=p && p+1<=sn && s[p]==pat.w) r.keyExists((Obj)(p+1));
}
};
break;
case _classAggregate:
stack.push(positions);
execute(pat,true);
r=stack.pop();
break;
case _classString:
case _classPatternAll:{
AggregateOrdered r1=positions;
for(auto pat1:(Aggregate)pat)
r1=match(s,r1,pat1);
if(!r) r=r1;else r+=r1;
break;
}
case _classPatternAny:
if(!r)
r=AggregateOrdered();
for(auto pat1:(Aggregate)pat)
match(s,positions,pat1,r);
break;
default:
assert0(false,"unexpected in matchAll");
break;
}
return r;
}
AggregateOrdered matchFor(Aggregate s,AggregateOrdered positions,Obj pat,uWord n1,uWord n2){
AggregateOrdered r=positions;
for(uWord i=n1;i--!=0;){
r=match(s,r,pat);
if(r.elements()==0) return r;
}
AggregateOrdered r1=r;
if(n2>=n1)
for(uWord i=n2-n1;i--!=0;){
r1=match(s,r1,pat);
if(r1.elements()==0) return r;
r+=r1;
}
return r;
}
void matchFor_(uWord n1,uWord n2){
Obj pat=stack.pop(),positions=stack.pop();
stack.push(matchFor((AggregateOrdered)stack[~1],positions,pat,n1,n2));
}