-
Notifications
You must be signed in to change notification settings - Fork 0
/
MatchAlgorithm.cls
161 lines (140 loc) · 4.4 KB
/
MatchAlgorithm.cls
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
"Filed out from Dolphin Smalltalk 7"!
Object subclass: #MatchAlgorithm
instanceVariableNames: 'string pattern start stop tokens failure ranges'
classVariableNames: ''
poolDictionaries: ''
classInstanceVariableNames: ''!
MatchAlgorithm guid: (GUID fromString: '{fb86432e-7484-40e1-9ffd-1f4642dcd99b}')!
MatchAlgorithm comment: ''!
!MatchAlgorithm categoriesForClass!Unclassified! !
!MatchAlgorithm methodsFor!
failBecause: aString
failure := aString!
failure
^failure!
hasMatched
^failure isNil and: [tokens isEmpty]!
hasTokens
^failure isNil and: [tokens notEmpty]!
index: anInteger
start := anInteger!
initialize
super initialize.
start := 1!
matchFirstStar
| range |
range := string start @ nil.
ranges add: tokens first -> range.
tokens removeFirst.
self hasTokens
ifTrue: [tokens first matchFirstAfterStartOn: self]
ifFalse: [
range y: string stop.
string stop: string start - 1]!
matchFirstToken
| token min match save |
token := tokens first.
min := token length.
match := false.
save := string start.
[
string length >= min and: [
match := string beginsWith: token.
match not]]
whileTrue: [string start: string start + 1].
match
ifTrue: [
ranges add: token -> (string start @ (string start + min - 1)).
string start: string start + token length.
tokens removeFirst]
ifFalse: [
tokens size = 1 ifTrue: [
string start: save.
^self privateMatchLastToken].
self
failBecause: token asString , ' not present at position '
, string start printString]!
matchFirstTokenAfterStar
| token i |
token := tokens first.
i := string indexOf: token.
i = 0
ifTrue: [
self
failBecause: token asString , ' not present in inteval ['
, string start printString
, ', '
, string stop printString]
ifFalse: [
ranges last value y: i - 1.
ranges add: token -> (i @ (i + token length - 1)).
string start: i + token length.
tokens removeFirst]!
matchLastToken
tokens size = 1
ifTrue: [self matchFirstToken]
ifFalse: [self privateMatchLastToken]!
matchNextToken
tokens first matchFirstOn: self!
matchRange
| sorted |
sorted := (ranges collect: [:r | r value]) select: [:p | p x <= p y].
sorted := sorted asSortedCollection: [:p :q | p x < q x].
^sorted notEmpty ifTrue: [sorted first x @ sorted last y]!
pattern: aStringPattern
pattern := aStringPattern!
privateMatchLastToken
| token min match |
token := tokens last.
min := token length.
match := false.
[
string length >= min and: [
match := string endsWith: token.
match not]]
whileTrue: [string stop: string stop - 1].
match
ifTrue: [
ranges add: token -> (string stop - min + 1 @ string stop).
string stop: string stop - token length.
tokens removeLast]
ifFalse: [
self
failBecause: token asString , ' not present at position '
, (string stop - token length + 1) printString]!
reset
| end |
failure := nil.
tokens := pattern tokens.
string start: start.
end := stop notNil ifTrue: [stop] ifFalse: [string string size].
string stop: end.
ranges := OrderedCollection new: tokens size!
run
self reset.
tokens isEmpty ifTrue: [^self].
tokens last matchLastOn: self.
[self hasTokens] whileTrue: [self matchNextToken]!
string: aString
string := MatchToken on: aString from: 1 to: aString size! !
!MatchAlgorithm categoriesFor: #failBecause:!private! !
!MatchAlgorithm categoriesFor: #failure!outputs!public! !
!MatchAlgorithm categoriesFor: #hasMatched!public!testing! !
!MatchAlgorithm categoriesFor: #hasTokens!public!testing! !
!MatchAlgorithm categoriesFor: #index:!inputs!public! !
!MatchAlgorithm categoriesFor: #initialize!initializing!public! !
!MatchAlgorithm categoriesFor: #matchFirstStar!computing!public! !
!MatchAlgorithm categoriesFor: #matchFirstToken!computing!public! !
!MatchAlgorithm categoriesFor: #matchFirstTokenAfterStar!computing!public! !
!MatchAlgorithm categoriesFor: #matchLastToken!computing!public! !
!MatchAlgorithm categoriesFor: #matchNextToken!computing!public! !
!MatchAlgorithm categoriesFor: #matchRange!outputs!public! !
!MatchAlgorithm categoriesFor: #pattern:!inputs!public! !
!MatchAlgorithm categoriesFor: #privateMatchLastToken!computing!public! !
!MatchAlgorithm categoriesFor: #reset!private! !
!MatchAlgorithm categoriesFor: #run!computing!public! !
!MatchAlgorithm categoriesFor: #string:!inputs!public! !
!MatchAlgorithm class methodsFor!
new
^super new initialize! !
!MatchAlgorithm class categoriesFor: #new!public! !