diff options
Diffstat (limited to 'testlabel.lua')
-rw-r--r-- | testlabel.lua | 139 |
1 files changed, 66 insertions, 73 deletions
diff --git a/testlabel.lua b/testlabel.lua index 72eb9aa..90a8f9e 100644 --- a/testlabel.lua +++ b/testlabel.lua | |||
@@ -110,102 +110,95 @@ checklabeq({nil, '11', 1}, p:match("x")) | |||
110 | checklabeq({nil, '11', 1}, p:match("kx")) | 110 | checklabeq({nil, '11', 1}, p:match("kx")) |
111 | 111 | ||
112 | 112 | ||
113 | -- throws a label that is not caught by the recovery operator | 113 | -- throws a label without a corresponding recovery rule |
114 | p = m.Rec(m.T(2), m.P"a", 1, 3) | 114 | p = m.P{ |
115 | r, l, poserr = p:match(s) | 115 | "S", |
116 | print(r, l, poserr) | 116 | S = m.T("bola"), |
117 | bolada = m.P"a" | ||
118 | } | ||
119 | r, l, poserr = p:match("abc") | ||
120 | assert(r == nil and l == 'bola' and poserr == 1) | ||
121 | |||
122 | -- throws a label without a corresponding recovery rule | ||
123 | -- T(2) indexes key ["2"] | ||
124 | p = m.P{ | ||
125 | "S", | ||
126 | S = m.T(2), | ||
127 | [2] = m.P"a" | ||
128 | } | ||
129 | r, l, poserr = p:match("abc") | ||
117 | assert(r == nil and l == '2' and poserr == 1) | 130 | assert(r == nil and l == '2' and poserr == 1) |
118 | 131 | ||
119 | -- wraps the previous pattern with a recovery that catches label "2" | 132 | -- throws a label with a corresponding recovery rule |
120 | p = m.Rec(p, m.P"a", 2) | 133 | p = m.P{ |
121 | assert(p:match(s) == 2) | 134 | "S", |
135 | S = m.T("bola"), | ||
136 | bola = m.P"a" | ||
137 | } | ||
138 | r, l, poserr = p:match("abc") | ||
139 | assert(r == 2) | ||
122 | 140 | ||
123 | -- throws a label that is caught by recovery | 141 | -- throws a label with a corresponding recovery rule |
124 | p = m.Rec(m.T(25), m.P"a", 25) | 142 | -- T(2) indexes key ["2"] |
125 | assert(p:match(s) == 2) | 143 | p = m.P{ |
144 | "S", | ||
145 | S = m.T(2), | ||
146 | ["2"] = m.P"a"^0 | ||
147 | } | ||
148 | r, l, poserr = p:match("aaabc") | ||
149 | assert(r == 4) | ||
150 | |||
151 | -- regular failure after the recovery | ||
152 | p = m.P{ | ||
153 | "S", | ||
154 | S = m.T(2), | ||
155 | ["2"] = m.P"a"^0 * m.P"c" | ||
156 | } | ||
157 | r, l, poserr = p:match("aaabc") | ||
158 | assert(r == nil and l == 'fail' and poserr == 4) | ||
126 | 159 | ||
127 | -- "fail" is label "0" | ||
128 | -- throws the "fail" label after the recovery | ||
129 | s = "bola" | 160 | s = "bola" |
130 | r, l, poserr = p:match("bola") | 161 | r, l, poserr = p:match("bola") |
131 | assert(r == nil and l == 0 and poserr == 1) | 162 | assert(r == nil and l == 'fail' and poserr == 1) |
132 | 163 | ||
133 | -- Recovery does not catch "fail" by default | 164 | -- Recovery rules do not catch "fail" by default |
134 | p = m.Rec(m.P"b", m.P"a", 1) | 165 | p = m.P{ |
166 | "S", | ||
167 | S = m.P"b" * m.T(2), | ||
168 | ["2"] = m.P"a"^0 | ||
169 | } | ||
170 | r, l, poserr = p:match("c") | ||
171 | assert(r == nil and l == 'fail' and poserr == 1) | ||
135 | 172 | ||
136 | r, l, poserr = p:match("abc") | 173 | assert(p:match("baa") == 4) |
137 | assert(r == nil and l == 0 and poserr == 1) | ||
138 | 174 | ||
139 | assert(p:match("bola") == 2) | ||
140 | 175 | ||
176 | -- recovery rules for "2" or "3" | ||
177 | -- when we use V instead of T, a recovery | ||
178 | -- rule becomes a regular grammar rule | ||
179 | p = m.P{ | ||
180 | "S", | ||
181 | S = (m.P"a" + m.T(2)) * m.T(3), | ||
182 | ["3"] = m.V"2", | ||
183 | ["2"] = m.P"a" + m.P"b", | ||
184 | } | ||
141 | 185 | ||
142 | -- recovery operator catches "1" or "3" | ||
143 | p = m.Rec((m.P"a" + m.T(1)) * m.T(3), (m.P"a" + m.P"b"), 1, 3) | ||
144 | assert(p:match("aac") == 3) | 186 | assert(p:match("aac") == 3) |
145 | assert(p:match("abc") == 3) | 187 | assert(p:match("abc") == 3) |
146 | r, l, poserr = p:match("acc") | 188 | r, l, poserr = p:match("acc") |
147 | assert(r == nil and l == 0 and poserr == 2) | 189 | assert(r == nil and l == 'fail' and poserr == 2) |
148 | 190 | ||
149 | --throws 1, recovery pattern matches 'b', throw 3, and rec pat mathces 'a' | 191 | --throws 2, recovery rule matches 'b', throw 3, and rec rule matches 'a' |
150 | assert(p:match("bac") == 3) | 192 | assert(p:match("bac") == 3) |
151 | 193 | ||
152 | r, l, poserr = p:match("cab") | 194 | r, l, poserr = p:match("cab") |
153 | assert(r == nil and l == 0 and poserr == 1) | 195 | assert(r == nil and l == 'fail' and poserr == 1) |
154 | |||
155 | |||
156 | -- associativity | ||
157 | -- (p1 / %1) //{1} (p2 / %2) //{2} p3 | ||
158 | -- left-associativity | ||
159 | -- ("a" //{1} "b") //{2} "c" | ||
160 | p = m.Rec(m.Rec(m.P"a" + m.T(1), m.P"b" + m.T(2), 1), m.P"c", 2) | ||
161 | assert(p:match("abc") == 2) | ||
162 | assert(p:match("bac") == 2) | ||
163 | assert(p:match("cab") == 2) | ||
164 | r, l, poserr = p:match("dab") | ||
165 | assert(r == nil and l == 0 and poserr == 1) | ||
166 | |||
167 | |||
168 | -- righ-associativity | ||
169 | -- "a" //{1} ("b" //{2} "c") | ||
170 | p = m.Rec(m.P"a" + m.T(1), m.Rec(m.P"b" + m.T(2), m.P"c", 2), 1) | ||
171 | assert(p:match("abc") == 2) | ||
172 | assert(p:match("bac") == 2) | ||
173 | assert(p:match("cab") == 2) | ||
174 | r, l, poserr = p:match("dab") | ||
175 | assert(r == nil and l == 0 and poserr == 1) | ||
176 | |||
177 | |||
178 | -- associativity -> in this case the error thrown by p1 is only | ||
179 | -- recovered when we have a left-associative operator | ||
180 | -- (p1 / %2) //{1} (p2 / %2) //{2} p3 | ||
181 | -- left-associativity | ||
182 | -- ("a" //{1} "b") //{2} "c" | ||
183 | p = m.Rec(m.Rec(m.P"a" + m.T(2), m.P"b" + m.T(2), 1), m.P"c", 2) | ||
184 | assert(p:match("abc") == 2) | ||
185 | r, l, poserr = p:match("bac") | ||
186 | assert(r == nil and l == 0 and poserr == 1) | ||
187 | assert(p:match("cab") == 2) | ||
188 | r, l, poserr = p:match("dab") | ||
189 | assert(r == nil and l == 0 and poserr == 1) | ||
190 | |||
191 | |||
192 | -- righ-associativity | ||
193 | -- "a" //{1} ("b" //{2} "c") | ||
194 | p = m.Rec(m.P"a" + m.T(2), m.Rec(m.P"b" + m.T(2), m.P"c", 2), 1) | ||
195 | assert(p:match("abc") == 2) | ||
196 | r, l, poserr = p:match("bac") | ||
197 | assert(r == nil and l == 2 and poserr == 1) | ||
198 | r, l, poserr = p:match("cab") | ||
199 | assert(r == nil and l == 2 and poserr == 1) | ||
200 | r, l, poserr = p:match("dab") | ||
201 | assert(r == nil and l == 2 and poserr == 1) | ||
202 | |||
203 | 196 | ||
204 | 197 | ||
205 | -- tests related to predicates | 198 | -- tests related to predicates |
206 | p = #m.T(1) + m.P"a" | 199 | p = #m.T(1) + m.P"a" |
207 | r, l, poserr = p:match("abc") | 200 | r, l, poserr = p:match("abc") |
208 | assert(r == nil and l == 1 and poserr == 1) | 201 | assert(r == nil and l == '1' and poserr == 1) |
209 | 202 | ||
210 | p = ##m.T(1) + m.P"a" | 203 | p = ##m.T(1) + m.P"a" |
211 | r, l, poserr = p:match("abc") | 204 | r, l, poserr = p:match("abc") |