aboutsummaryrefslogtreecommitdiff
path: root/relabel.lua
diff options
context:
space:
mode:
authorUndecidable Robot <undecidabot@gmail.com>2016-05-30 23:26:25 +0800
committerUndecidable Robot <undecidabot@gmail.com>2016-05-31 00:37:45 +0800
commitcfad25a1c830d86882b97cad6674bd941a3c6354 (patch)
tree1cebb40898503e2caf806492e1d472b1a8424b82 /relabel.lua
parent2fa6d9b25eb2fec85f9c1e9f67189b9b85ffa76b (diff)
downloadlpeglabel-cfad25a1c830d86882b97cad6674bd941a3c6354.tar.gz
lpeglabel-cfad25a1c830d86882b97cad6674bd941a3c6354.tar.bz2
lpeglabel-cfad25a1c830d86882b97cad6674bd941a3c6354.zip
Changing handling of non-syntax errors
Diffstat (limited to 'relabel.lua')
-rw-r--r--relabel.lua51
1 files changed, 24 insertions, 27 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