1
+ interface PExpr {
2
+ eval ( matcher : Matcher ) : CstNode ;
3
+ }
4
+
5
+ type RuleDict = {
6
+ [ name : string ] : PExpr ;
7
+ } ;
8
+
9
+ type CstNode = string | true | null | CstNode [ ] ;
10
+
11
+ interface MemoRec {
12
+ cst : CstNode ;
13
+ nextPos : number ;
14
+ used ?: boolean ;
15
+ }
16
+
17
+ type MemoCol = { [ key : string ] : MemoRec } ;
18
+
1
19
class Matcher {
2
- constructor ( rules ) {
20
+ rules : RuleDict ;
21
+ input : string = '' ;
22
+ pos : number = 0 ;
23
+ memoTable : MemoCol [ ] = [ ] ;
24
+
25
+ constructor ( rules : RuleDict ) {
3
26
this . rules = rules ;
4
27
}
5
28
6
- match ( input ) {
29
+ match ( input : string ) : CstNode {
7
30
this . input = input ;
8
31
this . pos = 0 ;
9
32
this . memoTable = [ ] ;
@@ -14,7 +37,7 @@ class Matcher {
14
37
return null ;
15
38
}
16
39
17
- memoTableAt ( pos ) {
40
+ memoTableAt ( pos : number ) : MemoCol {
18
41
let memo = this . memoTable [ pos ] ;
19
42
if ( ! memo ) {
20
43
// Lazily initialize the memo column.
@@ -23,17 +46,17 @@ class Matcher {
23
46
return memo ;
24
47
}
25
48
26
- hasMemoizedResult ( ruleName ) {
49
+ hasMemoizedResult ( ruleName : string ) {
27
50
return ! ! this . memoTableAt ( this . pos ) [ ruleName ] ;
28
51
}
29
52
30
- memoizeResult ( ruleName , pos , cst ) {
53
+ memoizeResult ( ruleName : string , pos : number , cst : CstNode ) : MemoRec {
31
54
const result = { cst, nextPos : this . pos } ;
32
55
this . memoTableAt ( pos ) [ ruleName ] = result ;
33
56
return result ;
34
57
}
35
58
36
- useMemoizedResult ( ruleName ) {
59
+ useMemoizedResult ( ruleName : string ) {
37
60
const result = this . memoTableAt ( this . pos ) [ ruleName ] ;
38
61
// Unconditionally set the position. If it was a failure, `result.cst`
39
62
// is `null` and the assignment to `this.pos` is a noop.
@@ -44,13 +67,13 @@ class Matcher {
44
67
return result . cst ;
45
68
}
46
69
47
- memoizeLRFailureAtCurrPos ( ruleName ) {
70
+ memoizeLRFailureAtCurrPos ( ruleName : string ) {
48
71
const lrFailure = { cst : null , nextPos : - 1 , used : false } ;
49
72
this . memoTableAt ( this . pos ) [ ruleName ] = lrFailure ;
50
73
return lrFailure ;
51
74
}
52
75
53
- consume ( c ) {
76
+ consume ( c : string ) {
54
77
if ( this . input [ this . pos ] === c ) {
55
78
this . pos ++ ;
56
79
return true ;
@@ -59,12 +82,14 @@ class Matcher {
59
82
}
60
83
}
61
84
62
- class RuleApplication {
63
- constructor ( ruleName ) {
85
+ class RuleApplication implements PExpr {
86
+ ruleName : string ;
87
+
88
+ constructor ( ruleName : string ) {
64
89
this . ruleName = ruleName ;
65
90
}
66
91
67
- eval ( matcher ) {
92
+ eval ( matcher : Matcher ) {
68
93
if ( matcher . hasMemoizedResult ( this . ruleName ) ) {
69
94
return matcher . useMemoizedResult ( this . ruleName ) ;
70
95
}
@@ -85,12 +110,14 @@ class RuleApplication {
85
110
}
86
111
}
87
112
88
- class Terminal {
89
- constructor ( str ) {
113
+ class Terminal implements PExpr {
114
+ str : string ;
115
+
116
+ constructor ( str : string ) {
90
117
this . str = str ;
91
118
}
92
119
93
- eval ( matcher ) {
120
+ eval ( matcher : Matcher ) {
94
121
for ( let i = 0 ; i < this . str . length ; i ++ ) {
95
122
if ( ! matcher . consume ( this . str [ i ] ) ) {
96
123
return null ;
@@ -100,12 +127,14 @@ class Terminal {
100
127
}
101
128
}
102
129
103
- class Choice {
104
- constructor ( exps ) {
130
+ class Choice implements PExpr {
131
+ exps : PExpr [ ] ;
132
+
133
+ constructor ( exps : PExpr [ ] ) {
105
134
this . exps = exps ;
106
135
}
107
136
108
- eval ( matcher ) {
137
+ eval ( matcher : Matcher ) {
109
138
const origPos = matcher . pos ;
110
139
for ( let i = 0 ; i < this . exps . length ; i ++ ) {
111
140
matcher . pos = origPos ;
@@ -118,13 +147,15 @@ class Choice {
118
147
}
119
148
}
120
149
121
- class Sequence {
122
- constructor ( exps ) {
150
+ class Sequence implements PExpr {
151
+ exps : PExpr [ ] ;
152
+
153
+ constructor ( exps : PExpr [ ] ) {
123
154
this . exps = exps ;
124
155
}
125
156
126
- eval ( matcher ) {
127
- const ans = [ ] ;
157
+ eval ( matcher : Matcher ) {
158
+ const ans : CstNode = [ ] ;
128
159
for ( let i = 0 ; i < this . exps . length ; i ++ ) {
129
160
const exp = this . exps [ i ] ;
130
161
const cst = exp . eval ( matcher ) ;
@@ -139,12 +170,14 @@ class Sequence {
139
170
}
140
171
}
141
172
142
- class Not {
143
- constructor ( exp ) {
173
+ class Not implements PExpr {
174
+ exp : PExpr ;
175
+
176
+ constructor ( exp : PExpr ) {
144
177
this . exp = exp ;
145
178
}
146
179
147
- eval ( matcher ) {
180
+ eval ( matcher : Matcher ) {
148
181
const origPos = matcher . pos ;
149
182
if ( this . exp . eval ( matcher ) === null ) {
150
183
matcher . pos = origPos ;
@@ -154,13 +187,15 @@ class Not {
154
187
}
155
188
}
156
189
157
- class Repetition {
158
- constructor ( exp ) {
190
+ class Repetition implements PExpr {
191
+ exp : PExpr ;
192
+
193
+ constructor ( exp : PExpr ) {
159
194
this . exp = exp ;
160
195
}
161
196
162
- eval ( matcher ) {
163
- const ans = [ ] ;
197
+ eval ( matcher : Matcher ) {
198
+ const ans : CstNode = [ ] ;
164
199
while ( true ) {
165
200
const origPos = matcher . pos ;
166
201
const cst = this . exp . eval ( matcher ) ;
0 commit comments