aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/exp.lua100
-rw-r--r--examples/expRec.lua58
-rw-r--r--examples/expRecAut.lua37
-rw-r--r--examples/farthest.lua16
-rw-r--r--examples/listId1.lua8
-rw-r--r--examples/listId2.lua19
-rw-r--r--examples/listId2Rec2.lua52
-rw-r--r--examples/listId2Rec2Cap.lua45
-rw-r--r--examples/listIdRe1.lua8
-rw-r--r--examples/listIdRe2.lua53
-rw-r--r--examples/tiny.lua147
-rw-r--r--lpvm.c4
12 files changed, 278 insertions, 269 deletions
diff --git a/examples/exp.lua b/examples/exp.lua
new file mode 100644
index 0000000..4afe83e
--- /dev/null
+++ b/examples/exp.lua
@@ -0,0 +1,100 @@
1-- Matthew's recovery example
2lpeg = require'lpeglabel'
3
4local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V
5local C, Cc, Ct, Cmt = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt
6local T = lpeg.T
7
8local labels = {
9 NoExp = "no expression found",
10 Extra = "extra characters found after the expression",
11 ExpTerm = "expected a term after the operator",
12 ExpExp = "expected an expression after the parenthesis",
13 MisClose = "missing a closing ')' after the expression",
14}
15
16local errors = {}
17
18local function expect(patt, labname)
19 function recorderror(input, pos)
20 table.insert(errors, {labname, pos})
21 return true
22 end
23 return patt + Cmt("", recorderror) * T(labname)
24end
25
26local num = R("09")^1 / tonumber
27local op = S("+-*/")
28
29local function compute(tokens)
30 local result = tokens[1]
31 for i = 2, #tokens, 2 do
32 if tokens[i] == '+' then
33 result = result + tokens[i+1]
34 elseif tokens[i] == '-' then
35 result = result - tokens[i+1]
36 elseif tokens[i] == '*' then
37 result = result * tokens[i+1]
38 elseif tokens[i] == '/' then
39 result = result / tokens[i+1]
40 else
41 error('unknown operation: ' .. tokens[i])
42 end
43 end
44 return result
45end
46
47local g = P {
48 "Exp",
49 Exp = Ct(V"Term" * (C(op) * V"Operand")^0) / compute;
50 Operand = expect(V"Term", "ExpTerm");
51 Term = num + V"Group";
52 Group = "(" * V"InnerExp" * expect(")", "MisClose");
53 InnerExp = expect(V"Exp", "ExpExp");
54 ExpTerm = Cc(0);
55 MisClose = P"";
56 ExpExp = (P(1) - ")")^0 * Cc(0);
57}
58
59g = expect(g, "NoExp") * expect(-P(1), "Extra")
60
61local function eval(input)
62 local result, label, suffix = g:match(input)
63 if #errors == 0 then
64 return result
65 else
66 local out = {}
67 for i, err in ipairs(errors) do
68 local pos = err[2]
69 local msg = labels[err[1]]
70 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
71 end
72 errors = {}
73 return nil, table.concat(out, "\n")
74 end
75end
76
77assert(eval "98-76*(54/32)" == 37.125)
78--> 37.125
79
80local e, msg = eval "(1+1-1*2/2"
81assert(e == nil and msg == "syntax error: missing a closing ')' after the expression (at index 11)")
82
83e, msg = eval "(1+)-1*(2/2)"
84assert(e == nil and msg == "syntax error: expected a term after the operator (at index 4)")
85
86e, msg = eval "(1+1)-1*(/2)"
87assert(e == nil and msg == "syntax error: expected an expression after the parenthesis (at index 10)")
88
89e, msg = eval "1+(1-(1*2))/2x"
90assert(e == nil and msg == "syntax error: extra characters found after the expression (at index 14)")
91
92e, msg = eval "-1+(1-(1*2))/2"
93assert(e == nil and msg == "syntax error: no expression found (at index 1)")
94
95e, msg = eval "(1+1-1*(2/2+)-():"
96assert(e == nil and msg == "syntax error: expected a term after the operator (at index 13)\n" ..
97 "syntax error: expected an expression after the parenthesis (at index 16)\n" ..
98 "syntax error: missing a closing ')' after the expression (at index 17)\n" ..
99 "syntax error: extra characters found after the expression (at index 17)")
100
diff --git a/examples/expRec.lua b/examples/expRec.lua
index 52bd40a..d111ab0 100644
--- a/examples/expRec.lua
+++ b/examples/expRec.lua
@@ -2,28 +2,17 @@ local m = require"lpeglabel"
2local re = require"relabel" 2local re = require"relabel"
3 3
4local labels = { 4local labels = {
5 {"ExpTermFirst", "expected an expression"}, 5 ExpTermFirst = "expected an expression",
6 {"ExpTermOp", "expected a term after the operator"}, 6 ExpTermOp = "expected a term after the operator",
7 {"MisClose", "missing a closing ')' after the expression"}, 7 MisClose = "missing a closing ')' after the expression",
8} 8}
9 9
10local function labelindex(labname)
11 for i, elem in ipairs(labels) do
12 if elem[1] == labname then
13 return i
14 end
15 end
16 error("could not find label: " .. labname)
17end
18
19local errors, subject 10local errors, subject
20 11
21local function expect(patt, labname) 12local function expect(patt, lab)
22 local i = labelindex(labname) 13 return patt + m.T(lab)
23 return patt + m.T(i)
24end 14end
25 15
26
27local num = m.R("09")^1 / tonumber 16local num = m.R("09")^1 / tonumber
28local op = m.S("+-") 17local op = m.S("+-")
29 18
@@ -41,22 +30,13 @@ local function compute(tokens)
41 return result 30 return result
42end 31end
43 32
44local g = m.P {
45 "Exp",
46 Exp = m.Ct(m.V"OperandFirst" * (m.C(op) * m.V"Operand")^0) / compute,
47 OperandFirst = expect(m.V"Term", "ExpTermFirst"),
48 Operand = expect(m.V"Term", "ExpTermOp"),
49 Term = num + m.V"Group",
50 Group = "(" * m.V"Exp" * expect(")", "MisClose"),
51}
52
53function recorderror(pos, lab) 33function recorderror(pos, lab)
54 local line, col = re.calcline(subject, pos) 34 local line, col = re.calcline(subject, pos)
55 table.insert(errors, { line = line, col = col, msg = labels[lab][2] }) 35 table.insert(errors, { line = line, col = col, msg = labels[lab] })
56end 36end
57 37
58function record (labname) 38function record (lab)
59 return (m.Cp() * m.Cc(labelindex(labname))) / recorderror 39 return (m.Cp() * m.Cc(lab)) / recorderror
60end 40end
61 41
62function sync (p) 42function sync (p)
@@ -67,21 +47,23 @@ function defaultValue (p)
67 return p or m.Cc(1000) 47 return p or m.Cc(1000)
68end 48end
69 49
70local grec = m.P { 50local g = m.P {
71 "S", 51 "Exp",
72 S = m.Rec(m.V"A", m.V"ErrExpTermFirst", labelindex("ExpTermFirst")), -- default value is 0 52 Exp = m.Ct(m.V"OperandFirst" * (m.C(op) * m.V"Operand")^0) / compute,
73 A = m.Rec(m.V"Sg", m.V"ErrExpTermOp", labelindex("ExpTermOp")), 53 OperandFirst = expect(m.V"Term", "ExpTermFirst"),
74 Sg = m.Rec(g, m.V"ErrMisClose", labelindex("MisClose")), 54 Operand = expect(m.V"Term", "ExpTermOp"),
75 ErrExpTermFirst = record("ExpTermFirst") * sync(op + ")") * defaultValue(), 55 Term = num + m.V"Group",
76 ErrExpTermOp = record("ExpTermOp") * sync(op + ")") * defaultValue(), 56 Group = "(" * m.V"Exp" * expect(")", "MisClose"),
77 ErrMisClose = record("MisClose") * sync(m.P")") * defaultValue(m.P""), 57 ExpTermFirst = record("ExpTermFirst") * sync(op + ")") * defaultValue(),
58 ExpTermOp = record("ExpTermOp") * sync(op + ")") * defaultValue(),
59 MisClose = record("MisClose") * sync(m.P")") * defaultValue(m.P""),
78} 60}
79 61
80local function eval(input) 62local function eval(input)
81 errors = {} 63 errors = {}
82 io.write("Input: ", input, "\n") 64 io.write("Input: ", input, "\n")
83 subject = input 65 subject = input
84 local result, label, suffix = grec:match(input) 66 local result, label, suffix = g:match(input)
85 io.write("Syntactic errors found: " .. #errors, "\n") 67 io.write("Syntactic errors found: " .. #errors, "\n")
86 if #errors > 0 then 68 if #errors > 0 then
87 local out = {} 69 local out = {}
diff --git a/examples/expRecAut.lua b/examples/expRecAut.lua
index b8280a7..18d7606 100644
--- a/examples/expRecAut.lua
+++ b/examples/expRecAut.lua
@@ -5,13 +5,11 @@ local num = m.R("09")^1 / tonumber
5local op = m.S("+-") 5local op = m.S("+-")
6 6
7local labels = {} 7local labels = {}
8local nlabels = 0
9 8
10local function newError(lab, msg, psync, pcap) 9local function newError(lab, msg, psync, pcap)
11 nlabels = nlabels + 1
12 psync = psync or m.P(-1) 10 psync = psync or m.P(-1)
13 pcap = pcap or m.P"" 11 pcap = pcap or m.P""
14 labels[lab] = { id = nlabels, msg = msg, psync = psync, pcap = pcap } 12 labels[lab] = { msg = msg, psync = psync, pcap = pcap }
15end 13end
16 14
17newError("ExpTermFirst", "expected an expression", op + ")", m.Cc(1000)) 15newError("ExpTermFirst", "expected an expression", op + ")", m.Cc(1000))
@@ -21,9 +19,8 @@ newError("Extra", "extra characters found after the expression")
21 19
22local errors, subject 20local errors, subject
23 21
24local function expect(patt, labname) 22local function expect(patt, lab)
25 local i = labels[labname].id 23 return patt + m.T(lab)
26 return patt + m.T(i)
27end 24end
28 25
29local function compute(tokens) 26local function compute(tokens)
@@ -40,15 +37,6 @@ local function compute(tokens)
40 return result 37 return result
41end 38end
42 39
43local g = m.P {
44 "Exp",
45 Exp = m.Ct(m.V"OperandFirst" * (m.C(op) * m.V"Operand")^0) / compute,
46 OperandFirst = expect(m.V"Term", "ExpTermFirst"),
47 Operand = expect(m.V"Term", "ExpTermOp"),
48 Term = num + m.V"Group",
49 Group = "(" * m.V"Exp" * expect(")", "MisClose"),
50}
51
52function recorderror(pos, lab) 40function recorderror(pos, lab)
53 local line, col = re.calcline(subject, pos) 41 local line, col = re.calcline(subject, pos)
54 table.insert(errors, { line = line, col = col, msg = labels[lab].msg }) 42 table.insert(errors, { line = line, col = col, msg = labels[lab].msg })
@@ -66,16 +54,29 @@ function defaultValue (p)
66 return p or m.Cc(1000) 54 return p or m.Cc(1000)
67end 55end
68 56
69local grec = g * expect(m.P(-1), "Extra") 57local g = {
58 "Exp",
59 Exp = m.Ct(m.V"OperandFirst" * (m.C(op) * m.V"Operand")^0) / compute,
60 OperandFirst = expect(m.V"Term", "ExpTermFirst"),
61 Operand = expect(m.V"Term", "ExpTermOp"),
62 Term = num + m.V"Group",
63 Group = "(" * m.V"Exp" * expect(")", "MisClose"),
64}
65
66-- set first rule
67g[1] = "S"
68g["S"] = g["Exp"] * expect(m.P(-1), "Extra")
70for k, v in pairs(labels) do 69for k, v in pairs(labels) do
71 grec = m.Rec(grec, record(k) * sync(v.psync) * v.pcap, v.id) 70 g[k] = record(k) * sync(v.psync) * v.pcap
72end 71end
73 72
73g = m.P(g)
74
74local function eval(input) 75local function eval(input)
75 errors = {} 76 errors = {}
76 io.write("Input: ", input, "\n") 77 io.write("Input: ", input, "\n")
77 subject = input 78 subject = input
78 local result, label, suffix = grec:match(input) 79 local result, label, suffix = g:match(input)
79 io.write("Syntactic errors found: " .. #errors, "\n") 80 io.write("Syntactic errors found: " .. #errors, "\n")
80 if #errors > 0 then 81 if #errors > 0 then
81 local out = {} 82 local out = {}
diff --git a/examples/farthest.lua b/examples/farthest.lua
index 9cbe03d..0dc8262 100644
--- a/examples/farthest.lua
+++ b/examples/farthest.lua
@@ -15,13 +15,13 @@ function matchPrint2(p, s)
15end 15end
16 16
17local p = m.P"a"^0 * m.P"b" + m.P"c" 17local p = m.P"a"^0 * m.P"b" + m.P"c"
18matchPrint(p, "abc") --> r: 3 lab: nil errpos: nil 18matchPrint(p, "abc") --> r: 3 lab: nil errpos: nil
19matchPrint(p, "c") --> r: 2 lab: nil errpos: nil 19matchPrint(p, "c") --> r: 2 lab: nil errpos: nil
20matchPrint(p, "aac") --> r: nil lab: 0 errpos: 3 20matchPrint(p, "aac") --> r: nil lab: fail errpos: 3
21matchPrint(p, "xxc") --> r: nil lab: 0 errpos: 1 21matchPrint(p, "xxc") --> r: nil lab: fail errpos: 1
22 22
23 23
24matchPrint2(p, "abc") --> r: 3 lab: nil sfail: nil 24matchPrint2(p, "abc") --> r: 3 lab: nil sfail: nil
25matchPrint2(p, "c") --> r: 2 lab: nil sfail: nil 25matchPrint2(p, "c") --> r: 2 lab: nil sfail: nil
26matchPrint2(p, "aac") --> r: nil lab: 0 sfail: c 26matchPrint2(p, "aac") --> r: nil lab: fail sfail: c
27matchPrint2(p, "xxc") --> r: nil lab: 0 sfail: xxc 27matchPrint2(p, "xxc") --> r: nil lab: fail sfail: xxc
diff --git a/examples/listId1.lua b/examples/listId1.lua
index 9bba783..e045ac1 100644
--- a/examples/listId1.lua
+++ b/examples/listId1.lua
@@ -7,8 +7,8 @@ local g = m.P{
7 "S", 7 "S",
8 S = m.V"Id" * m.V"List", 8 S = m.V"Id" * m.V"List",
9 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List", 9 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List",
10 Id = m.V"Sp" * id + m.T(1), 10 Id = m.V"Sp" * id + m.T'ErrId',
11 Comma = m.V"Sp" * "," + m.T(2), 11 Comma = m.V"Sp" * "," + m.T'ErrComma',
12 Sp = m.S" \n\t"^0, 12 Sp = m.S" \n\t"^0,
13} 13}
14 14
@@ -17,9 +17,9 @@ function mymatch (g, s)
17 if not r then 17 if not r then
18 local line, col = re.calcline(s, pos) 18 local line, col = re.calcline(s, pos)
19 local msg = "Error at line " .. line .. " (col " .. col .. ")" 19 local msg = "Error at line " .. line .. " (col " .. col .. ")"
20 if e == 1 then 20 if e == 'ErrId' then
21 return r, msg .. ": expecting an identifier before '" .. s:sub(pos) .. "'" 21 return r, msg .. ": expecting an identifier before '" .. s:sub(pos) .. "'"
22 elseif e == 2 then 22 elseif e == 'ErrComma' then
23 return r, msg .. ": expecting ',' before '" .. s:sub(pos) .. "'" 23 return r, msg .. ": expecting ',' before '" .. s:sub(pos) .. "'"
24 else 24 else
25 return r, msg 25 return r, msg
diff --git a/examples/listId2.lua b/examples/listId2.lua
index 592dae3..322d432 100644
--- a/examples/listId2.lua
+++ b/examples/listId2.lua
@@ -1,16 +1,11 @@
1local m = require'lpeglabel' 1local m = require'lpeglabel'
2local re = require'relabel' 2local re = require'relabel'
3 3
4local terror = {} 4local terror = {
5 5 ErrId = "expecting an identifier",
6local function newError(s) 6 ErrComma = "expecting ','",
7 table.insert(terror, s) 7 fail = "undefined"
8 return #terror 8}
9end
10
11local errUndef = newError("undefined")
12local errId = newError("expecting an identifier")
13local errComma = newError("expecting ','")
14 9
15local id = m.R'az'^1 10local id = m.R'az'^1
16 11
@@ -18,8 +13,8 @@ local g = m.P{
18 "S", 13 "S",
19 S = m.V"Id" * m.V"List", 14 S = m.V"Id" * m.V"List",
20 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List", 15 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List",
21 Id = m.V"Sp" * id + m.T(errId), 16 Id = m.V"Sp" * id + m.T'ErrId',
22 Comma = m.V"Sp" * "," + m.T(errComma), 17 Comma = m.V"Sp" * "," + m.T'ErrComma',
23 Sp = m.S" \n\t"^0, 18 Sp = m.S" \n\t"^0,
24} 19}
25 20
diff --git a/examples/listId2Rec2.lua b/examples/listId2Rec2.lua
index 3506095..09db5a6 100644
--- a/examples/listId2Rec2.lua
+++ b/examples/listId2Rec2.lua
@@ -1,51 +1,39 @@
1local m = require'lpeglabel' 1local m = require'lpeglabel'
2local re = require'relabel' 2local re = require'relabel'
3 3
4local terror = {} 4local terror = {
5 5 ErrId = "expecting an identifier",
6local function newError(s) 6 ErrComma = "expecting ','"
7 table.insert(terror, s)
8 return #terror
9end
10
11local errUndef = newError("undefined")
12local errId = newError("expecting an identifier")
13local errComma = newError("expecting ','")
14
15local id = m.R'az'^1
16
17local g = m.P{
18 "S",
19 S = m.V"Id" * m.V"List",
20 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List",
21 Id = m.V"Sp" * id + m.T(errId),
22 Comma = m.V"Sp" * "," + m.T(errComma),
23 Sp = m.S" \n\t"^0,
24} 7}
25 8
26local subject, errors 9local subject, errors
27 10
28function recorderror(pos, lab) 11local function recorderror(pos, lab)
29 local line, col = re.calcline(subject, pos) 12 local line, col = re.calcline(subject, pos)
30 table.insert(errors, { line = line, col = col, msg = terror[lab] }) 13 table.insert(errors, { line = line, col = col, msg = terror[lab] })
31end 14end
32 15
33function record (lab) 16local function record (lab)
34 return (m.Cp() * m.Cc(lab)) / recorderror 17 return (m.Cp() * m.Cc(lab)) / recorderror
35end 18end
36 19
37function sync (p) 20local function sync (p)
38 return (-p * m.P(1))^0 21 return (-p * m.P(1))^0
39end 22end
40 23
41local grec = m.P{ 24local id = m.R'az'^1
25
26local g = m.P{
42 "S", 27 "S",
43 S = m.Rec(m.Rec(g, m.V"ErrComma", errComma), m.V"ErrId", errId), 28 S = m.V"Id" * m.V"List",
44 ErrComma = record(errComma) * sync(id), 29 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List",
45 ErrId = record(errId) * sync(m.P",") 30 Id = m.V"Sp" * id + m.T'ErrId',
31 Comma = m.V"Sp" * "," + m.T'ErrComma',
32 Sp = m.S" \n\t"^0,
33 ErrId = record('ErrId') * sync(m.P","),
34 ErrComma = record('ErrComma') * sync(id),
46} 35}
47 36
48
49function mymatch (g, s) 37function mymatch (g, s)
50 errors = {} 38 errors = {}
51 subject = s 39 subject = s
@@ -61,7 +49,7 @@ function mymatch (g, s)
61 return r 49 return r
62end 50end
63 51
64print(mymatch(grec, "one,two")) 52print(mymatch(g, "one,two"))
65print(mymatch(grec, "one two three")) 53print(mymatch(g, "one two three"))
66print(mymatch(grec, "1,\n two, \n3,")) 54print(mymatch(g, "1,\n two, \n3,"))
67print(mymatch(grec, "one\n two123, \nthree,")) 55print(mymatch(g, "one\n two123, \nthree,"))
diff --git a/examples/listId2Rec2Cap.lua b/examples/listId2Rec2Cap.lua
index 32a4113..7fbe700 100644
--- a/examples/listId2Rec2Cap.lua
+++ b/examples/listId2Rec2Cap.lua
@@ -1,26 +1,9 @@
1local m = require'lpeglabel' 1local m = require'lpeglabel'
2local re = require'relabel' 2local re = require'relabel'
3 3
4local terror = {} 4local terror = {
5 5 ErrId = "expecting an identifier",
6local function newError(s) 6 ErrComma = "expecting ','"
7 table.insert(terror, s)
8 return #terror
9end
10
11local errUndef = newError("undefined")
12local errId = newError("expecting an identifier")
13local errComma = newError("expecting ','")
14
15local id = m.R'az'^1
16
17local g = m.P{
18 "S",
19 S = m.V"Id" * m.V"List",
20 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List",
21 Id = m.V"Sp" * m.C(id) + m.T(errId),
22 Comma = m.V"Sp" * "," + m.T(errComma),
23 Sp = m.S" \n\t"^0,
24} 7}
25 8
26local subject, errors 9local subject, errors
@@ -42,11 +25,17 @@ function defaultValue ()
42 return m.Cc"NONE" 25 return m.Cc"NONE"
43end 26end
44 27
45local grec = m.P{ 28local id = m.R'az'^1
29
30local g = m.P{
46 "S", 31 "S",
47 S = m.Rec(m.Rec(g, m.V"ErrComma", errComma), m.V"ErrId", errId), 32 S = m.V"Id" * m.V"List",
48 ErrComma = record(errComma) * sync(id), 33 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List",
49 ErrId = record(errId) * sync(m.P",") * defaultValue(), 34 Id = m.V"Sp" * m.C(id) + m.T'ErrId',
35 Comma = m.V"Sp" * "," + m.T'ErrComma',
36 Sp = m.S" \n\t"^0,
37 ErrId = record('ErrId') * sync(m.P",") * defaultValue(),
38 ErrComma = record('ErrComma') * sync(id),
50} 39}
51 40
52 41
@@ -73,7 +62,7 @@ function mymatch (g, s)
73 return r 62 return r
74end 63end
75 64
76mymatch(grec, "one,two") 65mymatch(g, "one,two")
77mymatch(grec, "one two three") 66mymatch(g, "one two three")
78mymatch(grec, "1,\n two, \n3,") 67mymatch(g, "1,\n two, \n3,")
79mymatch(grec, "one\n two123, \nthree,") 68mymatch(g, "one\n two123, \nthree,")
diff --git a/examples/listIdRe1.lua b/examples/listIdRe1.lua
index d60706a..ef38cfb 100644
--- a/examples/listIdRe1.lua
+++ b/examples/listIdRe1.lua
@@ -3,8 +3,8 @@ local re = require 'relabel'
3local g = re.compile[[ 3local g = re.compile[[
4 S <- Id List 4 S <- Id List
5 List <- !. / Comma Id List 5 List <- !. / Comma Id List
6 Id <- Sp [a-z]+ / %{2} 6 Id <- Sp [a-z]+ / %{ErrId}
7 Comma <- Sp ',' / %{3} 7 Comma <- Sp ',' / %{ErrComma}
8 Sp <- %s* 8 Sp <- %s*
9]] 9]]
10 10
@@ -13,9 +13,9 @@ function mymatch (g, s)
13 if not r then 13 if not r then
14 local line, col = re.calcline(s, pos) 14 local line, col = re.calcline(s, pos)
15 local msg = "Error at line " .. line .. " (col " .. col .. ")" 15 local msg = "Error at line " .. line .. " (col " .. col .. ")"
16 if e == 1 then 16 if e == 'ErrId' then
17 return r, msg .. ": expecting an identifier before '" .. s:sub(pos) .. "'" 17 return r, msg .. ": expecting an identifier before '" .. s:sub(pos) .. "'"
18 elseif e == 2 then 18 elseif e == 'ErrComma' then
19 return r, msg .. ": expecting ',' before '" .. s:sub(pos) .. "'" 19 return r, msg .. ": expecting ',' before '" .. s:sub(pos) .. "'"
20 else 20 else
21 return r, msg 21 return r, msg
diff --git a/examples/listIdRe2.lua b/examples/listIdRe2.lua
index 58ddedd..0ea7352 100644
--- a/examples/listIdRe2.lua
+++ b/examples/listIdRe2.lua
@@ -1,46 +1,33 @@
1local re = require 'relabel' 1local re = require 'relabel'
2 2
3local errinfo = { 3local errinfo = {
4 {"errUndef", "undefined"}, 4 ErrId = "expecting an identifier",
5 {"errId", "expecting an identifier"}, 5 ErrComma = "expecting ','",
6 {"errComma", "expecting ','"}, 6 fail = "undefined",
7} 7}
8 8
9local errmsgs = {} 9local function sync (p)
10local labels = {} 10 return '( !(' .. p .. ') .)*'
11
12for i, err in ipairs(errinfo) do
13 errmsgs[i] = err[2]
14 labels[err[1]] = i
15end 11end
16 12
17re.setlabels(labels)
18
19local g = re.compile[[
20 S <- Id List
21 List <- !. / Comma Id List
22 Id <- Sp {[a-z]+} / %{errId}
23 Comma <- Sp ',' / %{errComma}
24 Sp <- %s*
25]]
26
27local errors 13local errors
28 14
29function recorderror (subject, pos, label) 15local function recorderror (subject, pos, label)
30 local line, col = re.calcline(subject, pos) 16 local line, col = re.calcline(subject, pos)
31 table.insert(errors, { line = line, col = col, msg = errmsgs[labels[label]] }) 17 table.insert(errors, { line = line, col = col, msg = errinfo[label] })
32 return true 18 return true
33end 19end
34 20
35function sync (p) 21local g = re.compile([[
36 return '( !(' .. p .. ') .)*' 22 S <- Id List
37end 23 List <- !. / Comma Id List
24 Id <- (Sp {[a-z]+})^ErrId
25 Comma <- (Sp ',')^ErrComma
26 Sp <- %s*]] ..
27 "ErrId <- ('' -> 'ErrId' => recorderror) " .. sync('","') .. "-> default\n" ..
28 "ErrComma <- ('' -> 'ErrComma' => recorderror) " .. sync('[a-z]+'),
29 {default = "NONE", recorderror = recorderror})
38 30
39local grec = re.compile(
40 "S <- %g //{errComma} ErrComma //{errId} ErrId" .. "\n" ..
41 "ErrComma <- ('' -> 'errComma' => recorderror) " .. sync('[a-z]+') .. "\n" ..
42 "ErrId <- ('' -> 'errId' => recorderror) " .. sync('","') .. "-> default"
43 , {g = g, recorderror = recorderror, default = "NONE"})
44 31
45function mymatch (g, s) 32function mymatch (g, s)
46 errors = {} 33 errors = {}
@@ -65,7 +52,7 @@ function mymatch (g, s)
65 return r 52 return r
66end 53end
67 54
68mymatch(grec, "one,two") 55mymatch(g, "one,two")
69mymatch(grec, "one two three") 56mymatch(g, "one two three")
70mymatch(grec, "1,\n two, \n3,") 57mymatch(g, "1,\n two, \n3,")
71mymatch(grec, "one\n two123, \nthree,") 58mymatch(g, "one\n two123, \nthree,")
diff --git a/examples/tiny.lua b/examples/tiny.lua
index cc718e7..fe0bced 100644
--- a/examples/tiny.lua
+++ b/examples/tiny.lua
@@ -1,92 +1,63 @@
1local re = require 'relabel' 1local re = require 'relabel'
2 2
3local terror = {} 3local terror = {
4 4 cmdSeq = "Missing ';' in CmdSeq",
5local function newError(l, msg) 5 ifExp = "Error in expresion of 'if'",
6 table.insert(terror, { l = l, msg = msg} ) 6 ifThen = "Error matching 'then' keyword",
7end 7 ifThenCmdSeq = "Error matching CmdSeq of 'then' branch",
8 8 ifElseCmdSeq = "Error matching CmdSeq of 'else' branch",
9newError("errSemi", "Error: missing ';'") 9 ifEnd = "Error matching 'end' keyword of 'if'",
10newError("errExpIf", "Error: expected expression after 'if'") 10 repeatCmdSeq = "Error matching CmdSeq of 'repeat'",
11newError("errThen", "Error: expected 'then' keyword") 11 repeatUntil = "Error matching 'until' keyword",
12newError("errCmdSeq1", "Error: expected at least a command after 'then'") 12 repeatExp = "Error matching expression of 'until'",
13newError("errCmdSeq2", "Error: expected at least a command after 'else'") 13 assignOp = "Error matching ':='",
14newError("errEnd", "Error: expected 'end' keyword") 14 assignExp = "Error matching expression of assignment",
15newError("errCmdSeqRep", "Error: expected at least a command after 'repeat'") 15 readName = "Error matching 'NAME' after 'read'",
16newError("errUntil", "Error: expected 'until' keyword") 16 writeExp = "Error matching expression after 'write'",
17newError("errExpRep", "Error: expected expression after 'until'") 17 simpleExp = "Error matching 'SimpleExp'",
18newError("errAssignOp", "Error: expected ':=' in assigment") 18 term = "Error matching 'Term'",
19newError("errExpAssign", "Error: expected expression after ':='") 19 factor = "Error matching 'Factor'",
20newError("errReadName", "Error: expected an identifier after 'read'") 20 openParExp = "Error matching expression after '('",
21newError("errWriteExp", "Error: expected expression after 'write'") 21 closePar = "Error matching ')'",
22newError("errSimpExp", "Error: expected '(', ID, or number after '<' or '='") 22 undefined = "Undefined Error"
23newError("errTerm", "Error: expected '(', ID, or number after '+' or '-'") 23}
24newError("errFactor", "Error: expected '(', ID, or number after '*' or '/'") 24
25newError("errExpFac", "Error: expected expression after '('") 25g = re.compile([[
26newError("errClosePar", "Error: expected ')' after expression") 26 Tiny <- CmdSeq^undefined
27 27 CmdSeq <- (Cmd SEMICOLON^cmdSeq) (Cmd SEMICOLON^cmdSeq)*
28 28 Cmd <- IfCmd / RepeatCmd / ReadCmd / WriteCmd / AssignCmd
29local labelCode = {} 29 IfCmd <- IF Exp^ifExp THEN^ifThen CmdSeq^ifThenCmdSeq (ELSE CmdSeq^ifElseCmdSeq / '') END^ifEnd
30for k, v in ipairs(terror) do 30 RepeatCmd <- REPEAT CmdSeq^repeatCmdSeq UNTIL^repeatUntil Exp^repeatExp
31 labelCode[v.l] = k 31 AssignCmd <- NAME ASSIGNMENT^assignOp Exp^assignExp
32end 32 ReadCmd <- READ NAME^readName
33 33 WriteCmd <- WRITE Exp^writeExp
34re.setlabels(labelCode) 34 Exp <- SimpleExp ((LESS / EQUAL) SimpleExp^simpleExp / '')
35 35 SimpleExp <- Term ((ADD / SUB) Term^term)*
36local g = re.compile[[ 36 Term <- Factor ((MUL / DIV) Factor^factor)*
37 Tiny <- CmdSeq 37 Factor <- OPENPAR Exp^openParExp CLOSEPAR^closePar / NUMBER / NAME
38 CmdSeq <- (Cmd (SEMICOLON / ErrSemi)) (Cmd (SEMICOLON / ErrSemi))* 38 ADD <- Sp '+'
39 Cmd <- IfCmd / RepeatCmd / ReadCmd / WriteCmd / AssignCmd 39 ASSIGNMENT <- Sp ':='
40 IfCmd <- IF (Exp / ErrExpIf) (THEN / ErrThen) (CmdSeq / ErrCmdSeq1) (ELSE (CmdSeq / ErrCmdSeq2) / '') (END / ErrEnd) 40 CLOSEPAR <- Sp ')'
41 RepeatCmd <- REPEAT (CmdSeq / ErrCmdSeqRep) (UNTIL / ErrUntil) (Exp / ErrExpRep) 41 DIV <- Sp '/'
42 AssignCmd <- NAME (ASSIGNMENT / ErrAssignOp) (Exp / ErrExpAssign) 42 IF <- Sp 'if'
43 ReadCmd <- READ (NAME / ErrReadName) 43 ELSE <- Sp 'else'
44 WriteCmd <- WRITE (Exp / ErrWriteExp) 44 END <- Sp 'end'
45 Exp <- SimpleExp ((LESS / EQUAL) (SimpleExp / ErrSimpExp) / '') 45 EQUAL <- Sp '='
46 SimpleExp <- Term ((ADD / SUB) (Term / ErrTerm))* 46 LESS <- Sp '<'
47 Term <- Factor ((MUL / DIV) (Factor / ErrFactor))* 47 MUL <- Sp '*'
48 Factor <- OPENPAR (Exp / ErrExpFac) (CLOSEPAR / ErrClosePar) / NUMBER / NAME 48 NAME <- !RESERVED Sp [a-z]+
49 ErrSemi <- %{errSemi} 49 NUMBER <- Sp [0-9]+
50 ErrExpIf <- %{errExpIf} 50 OPENPAR <- Sp '('
51 ErrThen <- %{errThen} 51 READ <- Sp 'read'
52 ErrCmdSeq1 <- %{errCmdSeq1} 52 REPEAT <- Sp 'repeat'
53 ErrCmdSeq2 <- %{errCmdSeq2} 53 SEMICOLON <- Sp ';'
54 ErrEnd <- %{errEnd} 54 SUB <- Sp '-'
55 ErrCmdSeqRep <- %{errCmdSeqRep} 55 THEN <- Sp 'then'
56 ErrUntil <- %{errUntil} 56 UNTIL <- Sp 'until'
57 ErrExpRep <- %{errExpRep} 57 WRITE <- Sp 'write'
58 ErrAssignOp <- %{errAssignOp} 58 RESERVED <- (IF / ELSE / END / READ / REPEAT / THEN / UNTIL / WRITE) ![a-z]+
59 ErrExpAssign <- %{errExpAssign} 59 Sp <- (%s / %nl)*
60 ErrReadName <- %{errReadName} 60]], terror)
61 ErrWriteExp <- %{errWriteExp}
62 ErrSimpExp <- %{errSimpExp}
63 ErrTerm <- %{errTerm}
64 ErrFactor <- %{errFactor}
65 ErrExpFac <- %{errExpFac}
66 ErrClosePar <- %{errClosePar}
67 ADD <- Sp '+'
68 ASSIGNMENT <- Sp ':='
69 CLOSEPAR <- Sp ')'
70 DIV <- Sp '/'
71 IF <- Sp 'if'
72 ELSE <- Sp 'else'
73 END <- Sp 'end'
74 EQUAL <- Sp '='
75 LESS <- Sp '<'
76 MUL <- Sp '*'
77 NAME <- Sp !RESERVED [a-z]+
78 NUMBER <- Sp [0-9]+
79 OPENPAR <- Sp '('
80 READ <- Sp 'read'
81 REPEAT <- Sp 'repeat'
82 SEMICOLON <- Sp ';'
83 SUB <- Sp '-'
84 THEN <- Sp 'then'
85 UNTIL <- Sp 'until'
86 WRITE <- Sp 'write'
87 RESERVED <- (IF / ELSE / END / READ / REPEAT / THEN / UNTIL / WRITE) ![a-z]+
88 Sp <- %s*
89]]
90 61
91 62
92local function mymatch(g, s) 63local function mymatch(g, s)
@@ -94,7 +65,7 @@ local function mymatch(g, s)
94 if not r then 65 if not r then
95 local line, col = re.calcline(s, pos) 66 local line, col = re.calcline(s, pos)
96 local msg = "Error at line " .. line .. " (col " .. col .. "): " 67 local msg = "Error at line " .. line .. " (col " .. col .. "): "
97 return r, msg .. terror[e].msg 68 return r, msg .. terror[e]
98 end 69 end
99 return r 70 return r
100end 71end
diff --git a/lpvm.c b/lpvm.c
index f56f1d5..1eb7944 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -351,10 +351,6 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
351 while (!(stack-1)->predchoice) { 351 while (!(stack-1)->predchoice) {
352 --stack; 352 --stack;
353 } 353 }
354 /*if ((stack-1)->labenv == ANDPRED) {
355 printf("ANDPRED: stack - 1\n");
356 stack--;
357 }*/
358 *labelf = LFAIL; 354 *labelf = LFAIL;
359 } 355 }
360 goto fail; 356 goto fail;