From ef26e7c4b777ebe9c9c3844bcc818de811369fff Mon Sep 17 00:00:00 2001 From: Undecidable Robot Date: Thu, 18 Aug 2016 12:00:47 +0800 Subject: Removing error recovery (moving it out to a different branch) --- relabel.lua | 91 ++++---------------------- testrelabelparser.lua | 174 ++++---------------------------------------------- 2 files changed, 28 insertions(+), 237 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 labels[err[1]] = i end -local syntaxerrs = {} - local function expect (pattern, labelname) local label = labels[labelname] - local record = function (input, pos) - tinsert(syntaxerrs, { label = label, pos = pos }) - return true - end - return pattern + m.Cmt("", record) * m.T(label) + return pattern + m.T(label) end @@ -236,72 +230,20 @@ local function labchoice (...) return p end --- error recovery -local skip = m.P { "Skip", - Skip = (-m.P"/" * -m.P(name * arrow) * m.V"Ignored")^0 * m.Cc(dummy); - Ignored = m.V"Group" + any; - Group = "(" * (-m.P")" * m.V"Ignored")^0 * ")" - + "{" * (-m.P"}" * m.V"Ignored")^0 * "}" - + "[" * (-m.P"]" * m.V"Ignored")^0 * "]" - + "'" * (-m.P"'" * m.V"Ignored")^0 * "'" - + '"' * (-m.P'"' * m.V"Ignored")^0 * '"'; -} - -local ignore = m.Cmt(any, function (input, pos) - return syntaxerrs[#syntaxerrs].pos, dummy -end) - -local pointAtStart = m.Cmt(any, function (input, pos) - -- like ignore but makes the last syntax error point at the start - local ret = syntaxerrs[#syntaxerrs].pos - syntaxerrs[#syntaxerrs].pos = pos-1 - return ret, dummy -end) - - -local function labify (labelnames) - for i, l in ipairs(labelnames) do - labelnames[i] = labels[l] - end - return labelnames -end - -local labelset1 = labify { - "ExpPatt2", "ExpPatt3", - "ExpPatt4", "ExpPatt5", "ExpPatt6", "ExpPatt7", - "ExpPatt8", "ExpPattOrClose", - "ExpNum", "ExpCap", - "ExpName1", "ExpName2", "ExpName3", - "ExpNameOrLab", "ExpItem", - "MisClose6", "MisClose7" -} - -local labelset2 = labify { - "MisClose1", "MisClose2", "MisClose3", "MisClose4", "MisClose5" -} - -local labelset3 = labify { - "ExpPatt1", "ExpLab1", "ExpLab2", "MisClose7" -} - local exp = m.P{ "Exp", Exp = S * ( m.V"Grammar" - + (m.V"RecovSeq" * (S * "/" * m.Lc((m.Ct(m.V"Labels") + m.Cc(nil)) - * expect(S * m.V"RecovSeq", - "ExpPatt1"), - m.Cc(nil) * skip, - unpack(labelset3)) + + (m.V"Seq" * (S * "/" * (m.Ct(m.V"Labels") + m.Cc(nil)) + * expect(S * m.V"Seq", "ExpPatt1") )^0 ) / labchoice); Labels = m.P"{" * expect(S * m.V"Label", "ExpLab1") * (S * "," * expect(S * m.V"Label", "ExpLab2"))^0 * expect(S * "}", "MisClose7"); - RecovSeq = m.Lc(m.V"Seq", skip, unpack(labelset1)); Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix" * (S * m.V"Prefix")^0, mt.__mul); Prefix = "&" * expect(S * m.V"Prefix", "ExpPatt2") / mt.__len + "!" * expect(S * m.V"Prefix", "ExpPatt3") / mt.__unm + m.V"Suffix"; - Suffix = m.Cf(m.V"RecovPrimary" * + Suffix = m.Cf(m.V"Primary" * ( S * ( m.P"+" * m.Cc(1, mt.__pow) + m.P"*" * m.Cc(0, mt.__pow) + m.P"?" * m.Cc(-1, mt.__pow) @@ -318,11 +260,9 @@ local exp = m.P{ "Exp", "ExpName1") ) )^0, function (a,b,f) return f(a,b) end ); - RecovPrimary = m.Lc(m.V"Primary", ignore, unpack(labelset2)); Primary = "(" * expect(m.V"Exp", "ExpPatt4") * expect(S * ")", "MisClose1") - + m.Lc(String / mm.P, pointAtStart, - labels["MisTerm1"], labels["MisTerm2"]) - + m.Lc(Class, pointAtStart, labels["MisClose8"]) + + String / mm.P + + Class + defined + "%" * expect(m.V"Labels", "ExpNameOrLab") / mm.T + "{:" * (name * ":" + m.Cc(nil)) * expect(m.V"Exp", "ExpPatt5") @@ -374,23 +314,20 @@ local function compile (p, defs) if mm.type(p) == "pattern" then return p end -- already compiled p = p .. " " -- for better reporting of column numbers in errors when at EOF local ok, cp, label, suffix = pcall(function() return pattern:match(p, 1, defs) end) - if not ok and #syntaxerrs == 0 then + if not ok and cp then if type(cp) == "string" then cp = cp:gsub("^[^:]+:[^:]+: ", "") end error(cp, 3) end - if #syntaxerrs > 0 then + if not cp then local lines = splitlines(p) - local errors = {} - for i, err in ipairs(syntaxerrs) do - local line, col = lineno(p, err.pos) - tinsert(errors, "L" .. line .. ":C" .. col .. ": " .. errmsgs[err.label]) - tinsert(errors, lines[line]) - tinsert(errors, rep(" ", col-1) .. "^") - end - syntaxerrs = {} - error("syntax error(s) in pattern\n" .. concat(errors, "\n"), 3) + local line, col = lineno(p, #p - #suffix + 1) + local err = {} + tinsert(err, "L" .. line .. ":C" .. col .. ": " .. errmsgs[label]) + tinsert(err, lines[line]) + tinsert(err, rep(" ", col-1) .. "^") + error("syntax error(s) in pattern\n" .. concat(err, "\n"), 3) end return cp end diff --git a/testrelabelparser.lua b/testrelabelparser.lua index 1c5bb9f..46e01ee 100644 --- a/testrelabelparser.lua +++ b/testrelabelparser.lua @@ -199,9 +199,6 @@ testerror([[{ {~ } ~}]], [[ L1:C5: expected a pattern after '{~' { {~ } ~} ^ -L1:C10: missing closing '}' -{ {~ } ~} - ^ ]]) testerror([[{~ ^_^ ~}]], [[ @@ -419,9 +416,6 @@ L1:C17: missing closing ')' -- two errors are reported due to the ignore strategy testerror([[{: group: 'p' :}]], [[ L1:C9: missing closing ':}' -{: group: 'p' :} - ^ -L1:C9: unexpected characters after the pattern {: group: 'p' :} ^ ]]) @@ -447,9 +441,6 @@ testerror([['p' {| 'q' / 'r' }]], [[ L1:C17: missing closing '|}' 'p' {| 'q' / 'r' } ^ -L1:C18: unexpected characters after the pattern -'p' {| 'q' / 'r' } - ^ ]]) -- testing MisClose5 @@ -485,186 +476,49 @@ L1:C12: missing closing '}' -- testing MisClose8 testerror([[[]], [[ -L1:C1: missing closing ']' +L1:C2: missing closing ']' [ -^ + ^ ]]) testerror([[[^]], [[ -L1:C1: missing closing ']' +L1:C3: missing closing ']' [^ -^ + ^ ]]) testerror([[[] ]], [[ -L1:C1: missing closing ']' +L1:C4: missing closing ']' [] -^ + ^ ]]) testerror([[[^] ]], [[ -L1:C1: missing closing ']' +L1:C6: missing closing ']' [^] -^ + ^ ]]) testerror([[[_-___-_|]], [[ -L1:C1: missing closing ']' +L1:C10: missing closing ']' [_-___-_| -^ + ^ ]]) -- testing MisTerm1 testerror([['That is the question...]], [[ -L1:C1: missing terminating single quote +L1:C25: missing terminating single quote 'That is the question... -^ + ^ ]]) -- testing MisTerm2 testerror([[Q <- "To be or not to be...]], [[ -L1:C6: missing terminating double quote +L1:C28: missing terminating double quote Q <- "To be or not to be... - ^ -]]) - --- testing error recovery, more complex grammars (multiline), --- and pointer positions in error recovery - -testerror([[&'p'/&/!/'p'^'q']], [[ -L1:C7: expected a pattern after '&' -&'p'/&/!/'p'^'q' - ^ -L1:C9: expected a pattern after '!' -&'p'/&/!/'p'^'q' - ^ -L1:C14: expected a number after '^', '+' or '-' (no space) -&'p'/&/!/'p'^'q' - ^ -]]) - -testerror([[ - A <- 'a' (B 'b' - B <- 'x' / ! - C <- 'c' -]], [[ -L1:C18: missing closing ')' - A <- 'a' (B 'b' - ^ -L2:C15: expected a pattern after '!' - B <- 'x' / ! - ^ -]]) - -testerror([['a' / &@ ('c' / 'd')]], [[ -L1:C8: expected a pattern after '&' -'a' / &@ ('c' / 'd') - ^ -]]) - -testerror([['x' / & / 'y']], [[ -L1:C8: expected a pattern after '&' -'x' / & / 'y' - ^ -]]) - -testerror([[&/'p'/!/'q']], [[ -L1:C2: expected a pattern after '&' -&/'p'/!/'q' - ^ -L1:C8: expected a pattern after '!' -&/'p'/!/'q' - ^ -]]) - -testerror([['p'//'q']], [[ -L1:C5: expected a pattern after '/' or the label(s) -'p'//'q' - ^ -]]) - -testerror([[ - S <- 'forgot to close / T - T <- 'T' & / 't' -]], [[ -L1:C8: missing terminating single quote - S <- 'forgot to close / T - ^ -L2:C13: expected a pattern after '&' - T <- 'T' & / 't' - ^ -]]) - -testerror([[ - S <- [a-z / T - T <- 'x' / & / 'y' -]], [[ -L1:C8: missing closing ']' - S <- [a-z / T - ^ -L2:C15: expected a pattern after '&' - T <- 'x' / & / 'y' - ^ -]]) - -testerror([[ - S <- ('p' -- comment -]], [[ -L1:C12: missing closing ')' - S <- ('p' -- comment - ^ -]]) - --- an unfortunate second error exists because we don't know --- what's part of the quotation -testerror([[ - X <- ('p / Q (R - / S)) - Q <- 'q' - R <- 'r' - S <- 's' -]], [[ -L1:C9: missing terminating single quote - X <- ('p / Q (R - ^ -L2:C9: unexpected characters after the pattern - / S)) - ^ -]]) - -testerror([[ - A <- 'A' /{'lab'} B / ! - - B <- %{1, 2 3} 'b' / '6' & / 'B' - - C <- A^B -]], [[ -L1:C14: expected at least one label after '{' - A <- 'A' /{'lab'} B / ! - ^ -L1:C26: expected a pattern after '!' - A <- 'A' /{'lab'} B / ! - ^ -L3:C15: missing closing '}' - B <- %{1, 2 3} 'b' / '6' & / 'B' - ^ -L3:C29: expected a pattern after '&' - B <- %{1, 2 3} 'b' / '6' & / 'B' - ^ -L5:C10: expected a number after '^', '+' or '-' (no space) - C <- A^B - ^ -]]) - -testerror([['p'/{1/'q'/&]], [[ -L1:C7: missing closing '}' -'p'/{1/'q'/& - ^ -L1:C13: expected a pattern after '&' -'p'/{1/'q'/& - ^ + ^ ]]) -- testing non-syntax errors -- cgit v1.2.3-55-g6feb