aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--relabel.lua51
-rw-r--r--testerrors.lua38
2 files changed, 41 insertions, 48 deletions
diff --git a/relabel.lua b/relabel.lua
index d038531..1198be8 100644
--- a/relabel.lua
+++ b/relabel.lua
@@ -2,6 +2,7 @@
2 2
3-- imported functions and modules 3-- imported functions and modules
4local tonumber, type, print, error, ipairs = tonumber, type, print, error, ipairs 4local tonumber, type, print, error, ipairs = tonumber, type, print, error, ipairs
5local pcall = pcall
5local setmetatable = setmetatable 6local setmetatable = setmetatable
6local unpack, tinsert, concat = table.unpack or unpack, table.insert, table.concat 7local unpack, tinsert, concat = table.unpack or unpack, table.insert, table.concat
7local rep = string.rep 8local rep = string.rep
@@ -81,30 +82,27 @@ for i, err in ipairs(errinfo) do
81 labels[err[1]] = i 82 labels[err[1]] = i
82end 83end
83 84
84local errfound = {} 85local syntaxerrs = {}
85 86
86local function expect (pattern, labelname) 87local function expect (pattern, labelname)
87 local label = labels[labelname] 88 local label = labels[labelname]
88 local record = function (input, pos) 89 local record = function (input, pos)
89 tinsert(errfound, {label, pos}) 90 tinsert(syntaxerrs, {label, pos})
90 return true 91 return true
91 end 92 end
92 return pattern + m.Cmt("", record) * m.T(label) 93 return pattern + m.Cmt("", record) * m.T(label)
93end 94end
94 95
95local ignore = m.Cmt(any, function (input, pos) 96local ignore = m.Cmt(any, function (input, pos)
96 return errfound[#errfound][2], dummy 97 return syntaxerrs[#syntaxerrs][2], dummy
97end) 98end)
98 99
99local pointAtStart = m.Cmt(any, function (input, pos) 100local pointAtStart = m.Cmt(any, function (input, pos)
100 local ret = errfound[#errfound][2] 101 local ret = syntaxerrs[#syntaxerrs][2]
101 errfound[#errfound][2] = pos-1 102 syntaxerrs[#syntaxerrs][2] = pos-1
102 return ret, dummy 103 return ret, dummy
103end) 104end)
104 105
105local function adderror (message)
106 tinsert(errfound, {message})
107end
108 106
109-- Pre-defined names 107-- Pre-defined names
110local Predef = { nl = m.P"\n" } 108local Predef = { nl = m.P"\n" }
@@ -158,8 +156,7 @@ local I = m.P(function (s,i) print(i, s:sub(1, i-1)); return i end)
158local function getdef (id, defs) 156local function getdef (id, defs)
159 local c = defs and defs[id] 157 local c = defs and defs[id]
160 if not c then 158 if not c then
161 adderror("undefined name: " .. id) 159 error("undefined name: " .. id)
162 return nil
163 end 160 end
164 return c 161 return c
165end 162end
@@ -200,8 +197,7 @@ local String = "'" * m.C((any - "'" - m.P"\n")^0) * expect("'", "MisTerm1")
200local defined = "%" * Def / function (c,Defs) 197local defined = "%" * Def / function (c,Defs)
201 local cat = Defs and Defs[c] or Predef[c] 198 local cat = Defs and Defs[c] or Predef[c]
202 if not cat then 199 if not cat then
203 adderror ("name '" .. c .. "' undefined") 200 error("name '" .. c .. "' undefined")
204 return dummy
205 end 201 end
206 return cat 202 return cat
207end 203end
@@ -219,7 +215,7 @@ local Class =
219 215
220local function adddef (t, k, exp) 216local function adddef (t, k, exp)
221 if t[k] then 217 if t[k] then
222 adderror("'"..k.."' already defined as a rule") 218 error("'"..k.."' already defined as a rule")
223 else 219 else
224 t[k] = exp 220 t[k] = exp
225 end 221 end
@@ -231,8 +227,7 @@ local function firstdef (n, r) return adddef({n}, n, r) end
231 227
232local function NT (n, b) 228local function NT (n, b)
233 if not b then 229 if not b then
234 adderror("rule '"..n.."' used outside a grammar") 230 error("rule '"..n.."' used outside a grammar")
235 return dummy
236 else return mm.V(n) 231 else return mm.V(n)
237 end 232 end
238end 233end
@@ -370,21 +365,23 @@ end
370local function compile (p, defs) 365local function compile (p, defs)
371 if mm.type(p) == "pattern" then return p end -- already compiled 366 if mm.type(p) == "pattern" then return p end -- already compiled
372 p = p .. " " -- for better reporting of column numbers in errors when at EOF 367 p = p .. " " -- for better reporting of column numbers in errors when at EOF
373 local cp, label, suffix = pattern:match(p, 1, defs) 368 local ok, cp, label, suffix = pcall(function() return pattern:match(p, 1, defs) end)
374 if #errfound > 0 then 369 if not ok and #syntaxerrs == 0 then
370 if type(cp) == "string" then
371 cp = cp:gsub("^[^:]+:[^:]+: ", "")
372 end
373 error(cp)
374 end
375 if #syntaxerrs > 0 then
375 local lines = splitlines(p) 376 local lines = splitlines(p)
376 local errors = {} 377 local errors = {}
377 for i, err in ipairs(errfound) do 378 for i, err in ipairs(syntaxerrs) do
378 if #err == 1 then 379 local line, col = lineno(p, err[2])
379 tinsert(errors, err[1]) 380 tinsert(errors, "L" .. line .. ":C" .. col .. ": " .. errmsgs[err[1]])
380 else 381 tinsert(errors, lines[line])
381 local line, col = lineno(p, err[2]) 382 tinsert(errors, rep(" ", col-1) .. "^")
382 tinsert(errors, "L" .. line .. ":C" .. col .. ": " .. errmsgs[err[1]])
383 tinsert(errors, lines[line])
384 tinsert(errors, rep(" ", col-1) .. "^")
385 end
386 end 383 end
387 errfound = {} 384 syntaxerrs = {}
388 error("\n" .. concat(errors, "\n")) 385 error("\n" .. concat(errors, "\n"))
389 end 386 end
390 return cp 387 return cp
diff --git a/testerrors.lua b/testerrors.lua
index 010f111..d39b8b9 100644
--- a/testerrors.lua
+++ b/testerrors.lua
@@ -4,17 +4,23 @@ function testerror(repatt, msg)
4 msg = msg:match("^%s*(.-)%s*$") -- trim 4 msg = msg:match("^%s*(.-)%s*$") -- trim
5 local ok, err = pcall(function () re.compile(repatt) end) 5 local ok, err = pcall(function () re.compile(repatt) end)
6 assert(not ok) 6 assert(not ok)
7 err = err:match("^[^\n]*\n(.-)$") -- remove first line (filename) 7 if msg:match("^[^\n]*\n(.-)$") then
8 err = err:gsub("[ \t]*\n", "\n") -- remove trailing spaces 8 -- expecting a syntax error
9 -- if err ~= msg then 9 err = err:match("^[^\n]*\n(.-)$") -- remove first line (filename)
10 -- print(#err, #msg) 10 err = err:gsub("[ \t]*\n", "\n") -- remove trailing spaces
11 -- print('--') 11 -- if err ~= msg then
12 -- print(err) 12 -- print(#err, #msg)
13 -- print('--') 13 -- print('--')
14 -- print(msg) 14 -- print(err)
15 -- print('--') 15 -- print('--')
16 -- end 16 -- print(msg)
17 assert(err == msg) 17 -- print('--')
18 -- end
19 assert(err == msg)
20 else
21 -- expecting a non-syntax error
22 assert(err:match(msg))
23 end
18end 24end
19 25
20testerror([[~]], [[ 26testerror([[~]], [[
@@ -483,16 +489,10 @@ testerror([[
483 A <- 'and again' 489 A <- 'and again'
484]], [[ 490]], [[
485name 'nosuch' undefined 491name 'nosuch' undefined
486name 'def' undefined
487'A' already defined as a rule
488'A' already defined as a rule
489]]) 492]])
490 493
491testerror([[names not in grammar]], [[ 494testerror([[names not in grammar]], [[
492rule 'names' used outside a grammar 495rule 'names' used outside a grammar
493rule 'not' used outside a grammar
494rule 'in' used outside a grammar
495rule 'grammar' used outside a grammar
496]]) 496]])
497 497
498testerror([[ 498testerror([[
@@ -501,16 +501,12 @@ testerror([[
501 A <- 'and again' 501 A <- 'and again'
502]], [[ 502]], [[
503name 'nosuch' undefined 503name 'nosuch' undefined
504name 'def' undefined
505'A' already defined as a rule
506'A' already defined as a rule
507]]) 504]])
508 505
509testerror([[ A <- %nosuch ('error' ]], [[ 506testerror([[ A <- %nosuch ('error' ]], [[
510L1:C23: missing closing ')' 507L1:C23: missing closing ')'
511 A <- %nosuch ('error' 508 A <- %nosuch ('error'
512 ^ 509 ^
513name 'nosuch' undefined
514]]) 510]])
515 511
516testerror([['a' / &@ ('c' / 'd')]], [[ 512testerror([['a' / &@ ('c' / 'd')]], [[