diff options
author | Undecidable Robot <undecidabot@gmail.com> | 2016-08-18 12:00:47 +0800 |
---|---|---|
committer | Undecidable Robot <undecidabot@gmail.com> | 2016-08-18 12:00:47 +0800 |
commit | ef26e7c4b777ebe9c9c3844bcc818de811369fff (patch) | |
tree | 917926c063a8e713fcbfa138f53c722929131576 /relabel.lua | |
parent | 28a44f01cb7a75068b75a99c0badb3abdaf7047a (diff) | |
download | lpeglabel-ef26e7c4b777ebe9c9c3844bcc818de811369fff.tar.gz lpeglabel-ef26e7c4b777ebe9c9c3844bcc818de811369fff.tar.bz2 lpeglabel-ef26e7c4b777ebe9c9c3844bcc818de811369fff.zip |
Removing error recovery (moving it out to a different branch)
Diffstat (limited to 'relabel.lua')
-rw-r--r-- | relabel.lua | 91 |
1 files changed, 14 insertions, 77 deletions
diff --git a/relabel.lua b/relabel.lua index ff2e486..7fe8645 100644 --- a/relabel.lua +++ b/relabel.lua | |||
@@ -82,15 +82,9 @@ for i, err in ipairs(errinfo) do | |||
82 | labels[err[1]] = i | 82 | labels[err[1]] = i |
83 | end | 83 | end |
84 | 84 | ||
85 | local syntaxerrs = {} | ||
86 | |||
87 | local function expect (pattern, labelname) | 85 | local function expect (pattern, labelname) |
88 | local label = labels[labelname] | 86 | local label = labels[labelname] |
89 | local record = function (input, pos) | 87 | return pattern + m.T(label) |
90 | tinsert(syntaxerrs, { label = label, pos = pos }) | ||
91 | return true | ||
92 | end | ||
93 | return pattern + m.Cmt("", record) * m.T(label) | ||
94 | end | 88 | end |
95 | 89 | ||
96 | 90 | ||
@@ -236,72 +230,20 @@ local function labchoice (...) | |||
236 | return p | 230 | return p |
237 | end | 231 | end |
238 | 232 | ||
239 | -- error recovery | ||
240 | local skip = m.P { "Skip", | ||
241 | Skip = (-m.P"/" * -m.P(name * arrow) * m.V"Ignored")^0 * m.Cc(dummy); | ||
242 | Ignored = m.V"Group" + any; | ||
243 | Group = "(" * (-m.P")" * m.V"Ignored")^0 * ")" | ||
244 | + "{" * (-m.P"}" * m.V"Ignored")^0 * "}" | ||
245 | + "[" * (-m.P"]" * m.V"Ignored")^0 * "]" | ||
246 | + "'" * (-m.P"'" * m.V"Ignored")^0 * "'" | ||
247 | + '"' * (-m.P'"' * m.V"Ignored")^0 * '"'; | ||
248 | } | ||
249 | |||
250 | local ignore = m.Cmt(any, function (input, pos) | ||
251 | return syntaxerrs[#syntaxerrs].pos, dummy | ||
252 | end) | ||
253 | |||
254 | local pointAtStart = m.Cmt(any, function (input, pos) | ||
255 | -- like ignore but makes the last syntax error point at the start | ||
256 | local ret = syntaxerrs[#syntaxerrs].pos | ||
257 | syntaxerrs[#syntaxerrs].pos = pos-1 | ||
258 | return ret, dummy | ||
259 | end) | ||
260 | |||
261 | |||
262 | local function labify (labelnames) | ||
263 | for i, l in ipairs(labelnames) do | ||
264 | labelnames[i] = labels[l] | ||
265 | end | ||
266 | return labelnames | ||
267 | end | ||
268 | |||
269 | local labelset1 = labify { | ||
270 | "ExpPatt2", "ExpPatt3", | ||
271 | "ExpPatt4", "ExpPatt5", "ExpPatt6", "ExpPatt7", | ||
272 | "ExpPatt8", "ExpPattOrClose", | ||
273 | "ExpNum", "ExpCap", | ||
274 | "ExpName1", "ExpName2", "ExpName3", | ||
275 | "ExpNameOrLab", "ExpItem", | ||
276 | "MisClose6", "MisClose7" | ||
277 | } | ||
278 | |||
279 | local labelset2 = labify { | ||
280 | "MisClose1", "MisClose2", "MisClose3", "MisClose4", "MisClose5" | ||
281 | } | ||
282 | |||
283 | local labelset3 = labify { | ||
284 | "ExpPatt1", "ExpLab1", "ExpLab2", "MisClose7" | ||
285 | } | ||
286 | |||
287 | local exp = m.P{ "Exp", | 233 | local exp = m.P{ "Exp", |
288 | Exp = S * ( m.V"Grammar" | 234 | Exp = S * ( m.V"Grammar" |
289 | + (m.V"RecovSeq" * (S * "/" * m.Lc((m.Ct(m.V"Labels") + m.Cc(nil)) | 235 | + (m.V"Seq" * (S * "/" * (m.Ct(m.V"Labels") + m.Cc(nil)) |
290 | * expect(S * m.V"RecovSeq", | 236 | * expect(S * m.V"Seq", "ExpPatt1") |
291 | "ExpPatt1"), | ||
292 | m.Cc(nil) * skip, | ||
293 | unpack(labelset3)) | ||
294 | )^0 | 237 | )^0 |
295 | ) / labchoice); | 238 | ) / labchoice); |
296 | Labels = m.P"{" * expect(S * m.V"Label", "ExpLab1") | 239 | Labels = m.P"{" * expect(S * m.V"Label", "ExpLab1") |
297 | * (S * "," * expect(S * m.V"Label", "ExpLab2"))^0 | 240 | * (S * "," * expect(S * m.V"Label", "ExpLab2"))^0 |
298 | * expect(S * "}", "MisClose7"); | 241 | * expect(S * "}", "MisClose7"); |
299 | RecovSeq = m.Lc(m.V"Seq", skip, unpack(labelset1)); | ||
300 | Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix" * (S * m.V"Prefix")^0, mt.__mul); | 242 | Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix" * (S * m.V"Prefix")^0, mt.__mul); |
301 | Prefix = "&" * expect(S * m.V"Prefix", "ExpPatt2") / mt.__len | 243 | Prefix = "&" * expect(S * m.V"Prefix", "ExpPatt2") / mt.__len |
302 | + "!" * expect(S * m.V"Prefix", "ExpPatt3") / mt.__unm | 244 | + "!" * expect(S * m.V"Prefix", "ExpPatt3") / mt.__unm |
303 | + m.V"Suffix"; | 245 | + m.V"Suffix"; |
304 | Suffix = m.Cf(m.V"RecovPrimary" * | 246 | Suffix = m.Cf(m.V"Primary" * |
305 | ( S * ( m.P"+" * m.Cc(1, mt.__pow) | 247 | ( S * ( m.P"+" * m.Cc(1, mt.__pow) |
306 | + m.P"*" * m.Cc(0, mt.__pow) | 248 | + m.P"*" * m.Cc(0, mt.__pow) |
307 | + m.P"?" * m.Cc(-1, mt.__pow) | 249 | + m.P"?" * m.Cc(-1, mt.__pow) |
@@ -318,11 +260,9 @@ local exp = m.P{ "Exp", | |||
318 | "ExpName1") | 260 | "ExpName1") |
319 | ) | 261 | ) |
320 | )^0, function (a,b,f) return f(a,b) end ); | 262 | )^0, function (a,b,f) return f(a,b) end ); |
321 | RecovPrimary = m.Lc(m.V"Primary", ignore, unpack(labelset2)); | ||
322 | Primary = "(" * expect(m.V"Exp", "ExpPatt4") * expect(S * ")", "MisClose1") | 263 | Primary = "(" * expect(m.V"Exp", "ExpPatt4") * expect(S * ")", "MisClose1") |
323 | + m.Lc(String / mm.P, pointAtStart, | 264 | + String / mm.P |
324 | labels["MisTerm1"], labels["MisTerm2"]) | 265 | + Class |
325 | + m.Lc(Class, pointAtStart, labels["MisClose8"]) | ||
326 | + defined | 266 | + defined |
327 | + "%" * expect(m.V"Labels", "ExpNameOrLab") / mm.T | 267 | + "%" * expect(m.V"Labels", "ExpNameOrLab") / mm.T |
328 | + "{:" * (name * ":" + m.Cc(nil)) * expect(m.V"Exp", "ExpPatt5") | 268 | + "{:" * (name * ":" + m.Cc(nil)) * expect(m.V"Exp", "ExpPatt5") |
@@ -374,23 +314,20 @@ local function compile (p, defs) | |||
374 | if mm.type(p) == "pattern" then return p end -- already compiled | 314 | if mm.type(p) == "pattern" then return p end -- already compiled |
375 | p = p .. " " -- for better reporting of column numbers in errors when at EOF | 315 | p = p .. " " -- for better reporting of column numbers in errors when at EOF |
376 | local ok, cp, label, suffix = pcall(function() return pattern:match(p, 1, defs) end) | 316 | local ok, cp, label, suffix = pcall(function() return pattern:match(p, 1, defs) end) |
377 | if not ok and #syntaxerrs == 0 then | 317 | if not ok and cp then |
378 | if type(cp) == "string" then | 318 | if type(cp) == "string" then |
379 | cp = cp:gsub("^[^:]+:[^:]+: ", "") | 319 | cp = cp:gsub("^[^:]+:[^:]+: ", "") |
380 | end | 320 | end |
381 | error(cp, 3) | 321 | error(cp, 3) |
382 | end | 322 | end |
383 | if #syntaxerrs > 0 then | 323 | if not cp then |
384 | local lines = splitlines(p) | 324 | local lines = splitlines(p) |
385 | local errors = {} | 325 | local line, col = lineno(p, #p - #suffix + 1) |
386 | for i, err in ipairs(syntaxerrs) do | 326 | local err = {} |
387 | local line, col = lineno(p, err.pos) | 327 | tinsert(err, "L" .. line .. ":C" .. col .. ": " .. errmsgs[label]) |
388 | tinsert(errors, "L" .. line .. ":C" .. col .. ": " .. errmsgs[err.label]) | 328 | tinsert(err, lines[line]) |
389 | tinsert(errors, lines[line]) | 329 | tinsert(err, rep(" ", col-1) .. "^") |
390 | tinsert(errors, rep(" ", col-1) .. "^") | 330 | error("syntax error(s) in pattern\n" .. concat(err, "\n"), 3) |
391 | end | ||
392 | syntaxerrs = {} | ||
393 | error("syntax error(s) in pattern\n" .. concat(errors, "\n"), 3) | ||
394 | end | 331 | end |
395 | return cp | 332 | return cp |
396 | end | 333 | end |