1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
local re = require 'relabel'
local errinfo = {
ErrId = "expecting an identifier",
ErrComma = "expecting ','",
fail = "undefined",
}
local function sync (p)
return '( !(' .. p .. ') .)*'
end
local errors
local function recorderror (subject, pos, label)
local line, col = re.calcline(subject, pos)
table.insert(errors, { line = line, col = col, msg = errinfo[label] })
return true
end
local g = re.compile([[
S <- Id List
List <- !. / Comma Id List
Id <- (Sp {[a-z]+})^ErrId
Comma <- (Sp ',')^ErrComma
Sp <- %s*]] ..
"ErrId <- ('' -> 'ErrId' => recorderror) " .. sync('","') .. "-> default\n" ..
"ErrComma <- ('' -> 'ErrComma' => recorderror) " .. sync('[a-z]+'),
{default = "NONE", recorderror = recorderror})
function mymatch (g, s)
errors = {}
subject = s
io.write("Input: ", s, "\n")
local r = { g:match(s) }
io.write("Captures (separated by ';'): ")
for k, v in pairs(r) do
io.write(v .. "; ")
end
io.write("\nSyntactic errors found: " .. #errors)
if #errors > 0 then
io.write("\n")
local out = {}
for i, err in ipairs(errors) do
local msg = "Error at line " .. err.line .. " (col " .. err.col .. "): " .. err.msg
table.insert(out, msg)
end
io.write(table.concat(out, "\n"))
end
print("\n")
return r
end
mymatch(g, "one,two")
mymatch(g, "one two three")
mymatch(g, "1,\n two, \n3,")
mymatch(g, "one\n two123, \nthree,")
|