aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorSergio Queiroz <sqmedeiros@gmail.com>2016-12-13 13:53:49 -0300
committerSergio Queiroz <sqmedeiros@gmail.com>2016-12-13 13:53:49 -0300
commit09fab0decb7df93528ab40fcfd99587e9074c64f (patch)
treeecd7a763c7a08712f122945bb5ce1ed7d7e5f077 /examples
parentd80821d79376671371c15ded562fbe1a9bebc635 (diff)
parent1322d612d72ac658f2aa443dca94954b819c0993 (diff)
downloadlpeglabel-09fab0decb7df93528ab40fcfd99587e9074c64f.tar.gz
lpeglabel-09fab0decb7df93528ab40fcfd99587e9074c64f.tar.bz2
lpeglabel-09fab0decb7df93528ab40fcfd99587e9074c64f.zip
Merge branch 'recoveryresume'
Diffstat (limited to 'examples')
-rw-r--r--examples/expRec.lua128
-rw-r--r--examples/expRecAut.lua122
-rw-r--r--examples/expect.lua98
-rw-r--r--examples/listId1.lua12
-rw-r--r--examples/listId2.lua13
-rw-r--r--examples/listId2Rec2.lua67
-rw-r--r--examples/listId2Rec2Cap.lua79
-rw-r--r--examples/listIdCatch.lua28
-rw-r--r--examples/listIdCatchRe.lua34
-rw-r--r--examples/listIdRe1.lua8
-rw-r--r--examples/listIdRe2.lua61
-rw-r--r--examples/recovery.lua134
-rw-r--r--examples/recoveryOpFail.lua105
-rw-r--r--examples/recoveryOpLab.lua107
-rw-r--r--examples/tiny.lua84
-rwxr-xr-xexamples/typedlua/test.lua9
-rw-r--r--examples/typedlua/tllexer.lua11
-rw-r--r--examples/typedlua/tlparser.lua2
18 files changed, 509 insertions, 593 deletions
diff --git a/examples/expRec.lua b/examples/expRec.lua
new file mode 100644
index 0000000..5c5fd7d
--- /dev/null
+++ b/examples/expRec.lua
@@ -0,0 +1,128 @@
1local m = require"lpeglabelrec"
2local re = require"relabelrec"
3
4local labels = {
5 {"ExpTermFirst", "expected an expression"},
6 {"ExpTermOp", "expected a term after the operator"},
7 {"MisClose", "missing a closing ')' after the expression"},
8}
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
20
21local function expect(patt, labname)
22 local i = labelindex(labname)
23 return patt + m.T(i)
24end
25
26
27local num = m.R("09")^1 / tonumber
28local op = m.S("+-")
29
30local function compute(tokens)
31 local result = tokens[1]
32 for i = 2, #tokens, 2 do
33 if tokens[i] == '+' then
34 result = result + tokens[i+1]
35 elseif tokens[i] == '-' then
36 result = result - tokens[i+1]
37 else
38 error('unknown operation: ' .. tokens[i])
39 end
40 end
41 return result
42end
43
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)
54 local line, col = re.calcline(subject, pos)
55 table.insert(errors, { line = line, col = col, msg = labels[lab][2] })
56end
57
58function record (labname)
59 return (m.Cp() * m.Cc(labelindex(labname))) / recorderror
60end
61
62function sync (p)
63 return (-p * m.P(1))^0
64end
65
66function defaultValue (p)
67 return p or m.Cc(1000)
68end
69
70local grec = m.P {
71 "S",
72 S = m.Rec(m.V"A", m.V"ErrExpTermFirst", labelindex("ExpTermFirst")), -- default value is 0
73 A = m.Rec(m.V"Sg", m.V"ErrExpTermOp", labelindex("ExpTermOp")),
74 Sg = m.Rec(g, m.V"ErrMisClose", labelindex("MisClose")),
75 ErrExpTermFirst = record("ExpTermFirst") * sync(op + ")") * defaultValue(),
76 ErrExpTermOp = record("ExpTermOp") * sync(op + ")") * defaultValue(),
77 ErrMisClose = record("MisClose") * sync(m.P")") * defaultValue(m.P""),
78}
79
80local function eval(input)
81 errors = {}
82 io.write("Input: ", input, "\n")
83 subject = input
84 local result, label, suffix = grec:match(input)
85 io.write("Syntactic errors found: " .. #errors, "\n")
86 if #errors > 0 then
87 local out = {}
88 for i, err in ipairs(errors) do
89 local pos = err.col
90 local msg = err.msg
91 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
92 end
93 print(table.concat(out, "\n"))
94 end
95 io.write("Result = ")
96 return result
97end
98
99print(eval "90-70-(5)+3")
100--> 20
101
102print(eval "15+")
103--> 2 + 0
104
105print(eval "-2")
106--> 0 - 2
107
108print(eval "1+3+-9")
109--> 1 + 3 + [0] - 9
110
111print(eval "1+()3+")
112--> 1 + ([0]) [3 +] [0]
113
114print(eval "8-(2+)-5")
115--> 8 - (2 + [0]) - 5
116
117print(eval "()")
118
119print(eval "")
120
121print(eval "1+()+")
122
123print(eval "1+(")
124
125print(eval "3)")
126
127print(eval "11+())3")
128
diff --git a/examples/expRecAut.lua b/examples/expRecAut.lua
new file mode 100644
index 0000000..f870d73
--- /dev/null
+++ b/examples/expRecAut.lua
@@ -0,0 +1,122 @@
1local m = require"lpeglabelrec"
2local re = require"relabelrec"
3
4local num = m.R("09")^1 / tonumber
5local op = m.S("+-")
6
7local labels = {}
8local nlabels = 0
9
10local function newError(lab, msg, psync, pcap)
11 nlabels = nlabels + 1
12 psync = psync or m.P(-1)
13 pcap = pcap or m.P""
14 labels[lab] = { id = nlabels, msg = msg, psync = psync, pcap = pcap }
15end
16
17newError("ExpTermFirst", "expected an expression", op + ")", m.Cc(1000))
18newError("ExpTermOp", "expected a term after the operator", op + ")", m.Cc(1000))
19newError("MisClose", "missing a closing ')' after the expression", m.P")")
20newError("Extra", "extra characters found after the expression")
21
22local errors, subject
23
24local function expect(patt, labname)
25 local i = labels[labname].id
26 return patt + m.T(i)
27end
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 else
37 error('unknown operation: ' .. tokens[i])
38 end
39 end
40 return result
41end
42
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)
53 local line, col = re.calcline(subject, pos)
54 table.insert(errors, { line = line, col = col, msg = labels[lab].msg })
55end
56
57function record (labname)
58 return (m.Cp() * m.Cc(labname)) / recorderror
59end
60
61function sync (p)
62 return (-p * m.P(1))^0
63end
64
65function defaultValue (p)
66 return p or m.Cc(1000)
67end
68
69local grec = g * expect(m.P(-1), "Extra")
70for k, v in pairs(labels) do
71 grec = m.Rec(grec, record(k) * sync(v.psync) * v.pcap, v.id)
72end
73
74local function eval(input)
75 errors = {}
76 io.write("Input: ", input, "\n")
77 subject = input
78 local result, label, suffix = grec:match(input)
79 io.write("Syntactic errors found: " .. #errors, "\n")
80 if #errors > 0 then
81 local out = {}
82 for i, err in ipairs(errors) do
83 local pos = err.col
84 local msg = err.msg
85 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
86 end
87 print(table.concat(out, "\n"))
88 end
89 io.write("Result = ")
90 return result
91end
92
93print(eval "90-70-(5)+3")
94--> 18
95
96print(eval "15+")
97--> 2 + 0
98
99print(eval "-2")
100--> 0 - 2
101
102print(eval "1+3+-9")
103--> 1 + 3 + [0] - 9
104
105print(eval "1+()3+")
106--> 1 + ([0]) [+] 3 + [0]
107
108print(eval "8-(2+)-5")
109--> 8 - (2 + [0]) - 5
110
111print(eval "()")
112
113print(eval "")
114
115print(eval "1+()+")
116
117print(eval "1+(")
118
119print(eval "3)")
120
121print(eval "11+()3")
122--> 1 + ([0]) [+] 3 + [0]
diff --git a/examples/expect.lua b/examples/expect.lua
deleted file mode 100644
index cb68d38..0000000
--- a/examples/expect.lua
+++ /dev/null
@@ -1,98 +0,0 @@
1local lpeg = require"lpeglabel"
2
3local R, S, P, V, C, Ct, T = lpeg.R, lpeg.S, lpeg.P, lpeg.V, lpeg.C, lpeg.Ct, lpeg.T
4
5-- The `labels` table contains the list of labels that we will be using
6-- as well as the corresponding error message for each label, which will
7-- be used in our error reporting later on.
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
16-- The `expect` function takes a pattern and a label defined in
17-- the `labels` table and returns a pattern that throws the specified
18-- label if the original pattern fails to match.
19-- Note: LPegLabel requires us to use integers for the labels, so we
20-- use the index of the label in the `labels` table to represent it.
21local function expect(patt, labname)
22 for i, elem in ipairs(labels) do
23 if elem[1] == labname then
24 return patt + T(i)
25 end
26 end
27
28 error("could not find label: " .. labname)
29end
30
31local num = R("09")^1 / tonumber
32local op = S("+-*/")
33
34-- The `compute` function takes an alternating list of numbers and
35-- operators and computes the result of applying the operations
36-- to the numbers in a left to right order (no operator precedence).
37local function compute(tokens)
38 local result = tokens[1]
39 for i = 2, #tokens, 2 do
40 if tokens[i] == '+' then
41 result = result + tokens[i+1]
42 elseif tokens[i] == '-' then
43 result = result - tokens[i+1]
44 elseif tokens[i] == '*' then
45 result = result * tokens[i+1]
46 elseif tokens[i] == '/' then
47 result = result / tokens[i+1]
48 else
49 error('unknown operation: ' .. tokens[i])
50 end
51 end
52 return result
53end
54
55-- Our grammar is a simple arithmetic expression of integers that
56-- does not take operator precedence into account but allows grouping
57-- via parenthesis.
58local g = P {
59 "Exp",
60 Exp = Ct(V"Term" * (C(op) * expect(V"Term", "ExpTerm"))^0) / compute;
61 Term = num + V"Group";
62 Group = "(" * expect(V"Exp", "ExpExp") * expect(")", "MisClose");
63}
64
65g = expect(g, "NoExp") * expect(-P(1), "Extra")
66
67-- The `eval` function takes an input string to match against the grammar
68-- we've just defined. If the input string matches, then the result of the
69-- computation is returned, otherwise we return the error message and
70-- position of the first failure encountered.
71local function eval(input)
72 local result, label, suffix = g:match(input)
73 if result ~= nil then
74 return result
75 else
76 local pos = input:len() - suffix:len() + 1
77 local msg = labels[label][2]
78 return nil, "syntax error: " .. msg .. " (at index " .. pos .. ")"
79 end
80end
81
82print(eval "98-76*(54/32)")
83--> 37.125
84
85print(eval "(1+1-1*2/2")
86--> syntax error: missing a closing ')' after the expression (at index 11)
87
88print(eval "(1+)-1*(2/2)")
89--> syntax error: expected a term after the operator (at index 4)
90
91print(eval "(1+1)-1*(/2)")
92--> syntax error: expected an expression after the parenthesis (at index 10)
93
94print(eval "1+(1-(1*2))/2x")
95--> syntax error: extra chracters found after the expression (at index 14)
96
97print(eval "-1+(1-(1*2))/2")
98--> syntax error: no expression found (at index 1)
diff --git a/examples/listId1.lua b/examples/listId1.lua
index 8976f5f..dee46e9 100644
--- a/examples/listId1.lua
+++ b/examples/listId1.lua
@@ -1,12 +1,14 @@
1local m = require'lpeglabel' 1local m = require'lpeglabelrec'
2local re = require'relabel' 2local re = require'relabelrec'
3
4local id = m.R'az'^1
3 5
4local g = m.P{ 6local g = m.P{
5 "S", 7 "S",
6 S = m.V"Id" * m.V"List", 8 S = m.V"Id" * m.V"List",
7 List = -m.P(1) + (m.V"Comma" + m.T(2)) * (m.V"Id" + m.T(1)) * m.V"List", 9 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List",
8 Id = m.V"Sp" * m.R'az'^1, 10 Id = m.V"Sp" * id + m.T(1),
9 Comma = m.V"Sp" * ",", 11 Comma = m.V"Sp" * "," + m.T(2),
10 Sp = m.S" \n\t"^0, 12 Sp = m.S" \n\t"^0,
11} 13}
12 14
diff --git a/examples/listId2.lua b/examples/listId2.lua
index 509fda4..46f0063 100644
--- a/examples/listId2.lua
+++ b/examples/listId2.lua
@@ -1,5 +1,5 @@
1local m = require'lpeglabel' 1local m = require'lpeglabelrec'
2local re = require'relabel' 2local re = require'relabelrec'
3 3
4local terror = {} 4local terror = {}
5 5
@@ -12,15 +12,18 @@ local errUndef = newError("undefined")
12local errId = newError("expecting an identifier") 12local errId = newError("expecting an identifier")
13local errComma = newError("expecting ','") 13local errComma = newError("expecting ','")
14 14
15local id = m.R'az'^1
16
15local g = m.P{ 17local g = m.P{
16 "S", 18 "S",
17 S = m.V"Id" * m.V"List", 19 S = m.V"Id" * m.V"List",
18 List = -m.P(1) + (m.V"Comma" + m.T(errComma)) * (m.V"Id" + m.T(errId)) * m.V"List", 20 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List",
19 Id = m.V"Sp" * m.R'az'^1, 21 Id = m.V"Sp" * id + m.T(errId),
20 Comma = m.V"Sp" * ",", 22 Comma = m.V"Sp" * "," + m.T(errComma),
21 Sp = m.S" \n\t"^0, 23 Sp = m.S" \n\t"^0,
22} 24}
23 25
26
24function mymatch (g, s) 27function mymatch (g, s)
25 local r, e, sfail = g:match(s) 28 local r, e, sfail = g:match(s)
26 if not r then 29 if not r then
diff --git a/examples/listId2Rec2.lua b/examples/listId2Rec2.lua
new file mode 100644
index 0000000..c6705dd
--- /dev/null
+++ b/examples/listId2Rec2.lua
@@ -0,0 +1,67 @@
1local m = require'lpeglabelrec'
2local re = require'relabelrec'
3
4local terror = {}
5
6local function newError(s)
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}
25
26local subject, errors
27
28function recorderror(pos, lab)
29 local line, col = re.calcline(subject, pos)
30 table.insert(errors, { line = line, col = col, msg = terror[lab] })
31end
32
33function record (lab)
34 return (m.Cp() * m.Cc(lab)) / recorderror
35end
36
37function sync (p)
38 return (-p * m.P(1))^0
39end
40
41local grec = m.P{
42 "S",
43 S = m.Rec(m.Rec(g, m.V"ErrComma", errComma), m.V"ErrId", errId),
44 ErrComma = record(errComma) * sync(id),
45 ErrId = record(errId) * sync(m.P",")
46}
47
48
49function mymatch (g, s)
50 errors = {}
51 subject = s
52 local r, e, sfail = g:match(s)
53 if #errors > 0 then
54 local out = {}
55 for i, err in ipairs(errors) do
56 local msg = "Error at line " .. err.line .. " (col " .. err.col .. "): " .. err.msg
57 table.insert(out, msg)
58 end
59 return nil, table.concat(out, "\n") .. "\n"
60 end
61 return r
62end
63
64print(mymatch(grec, "one,two"))
65print(mymatch(grec, "one two three"))
66print(mymatch(grec, "1,\n two, \n3,"))
67print(mymatch(grec, "one\n two123, \nthree,"))
diff --git a/examples/listId2Rec2Cap.lua b/examples/listId2Rec2Cap.lua
new file mode 100644
index 0000000..1c22c88
--- /dev/null
+++ b/examples/listId2Rec2Cap.lua
@@ -0,0 +1,79 @@
1local m = require'lpeglabelrec'
2local re = require'relabelrec'
3
4local terror = {}
5
6local function newError(s)
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}
25
26local subject, errors
27
28function recorderror(pos, lab)
29 local line, col = re.calcline(subject, pos)
30 table.insert(errors, { line = line, col = col, msg = terror[lab] })
31end
32
33function record (lab)
34 return (m.Cp() * m.Cc(lab)) / recorderror
35end
36
37function sync (p)
38 return (-p * m.P(1))^0
39end
40
41function defaultValue ()
42 return m.Cc"NONE"
43end
44
45local grec = m.P{
46 "S",
47 S = m.Rec(m.Rec(g, m.V"ErrComma", errComma), m.V"ErrId", errId),
48 ErrComma = record(errComma) * sync(id),
49 ErrId = record(errId) * sync(m.P",") * defaultValue(),
50}
51
52
53function mymatch (g, s)
54 errors = {}
55 subject = s
56 io.write("Input: ", s, "\n")
57 local r = { g:match(s) }
58 io.write("Captures (separated by ';'): ")
59 for k, v in pairs(r) do
60 io.write(v .. "; ")
61 end
62 io.write("\nSyntactic errors found: " .. #errors)
63 if #errors > 0 then
64 io.write("\n")
65 local out = {}
66 for i, err in ipairs(errors) do
67 local msg = "Error at line " .. err.line .. " (col " .. err.col .. "): " .. err.msg
68 table.insert(out, msg)
69 end
70 io.write(table.concat(out, "\n"))
71 end
72 print("\n")
73 return r
74end
75
76mymatch(grec, "one,two")
77mymatch(grec, "one two three")
78mymatch(grec, "1,\n two, \n3,")
79mymatch(grec, "one\n two123, \nthree,")
diff --git a/examples/listIdCatch.lua b/examples/listIdCatch.lua
deleted file mode 100644
index 5ad6f2d..0000000
--- a/examples/listIdCatch.lua
+++ /dev/null
@@ -1,28 +0,0 @@
1local m = require'lpeglabel'
2
3local terror = {}
4
5local function newError(s)
6 table.insert(terror, s)
7 return #terror
8end
9
10local errUndef = newError("undefined")
11local errId = newError("expecting an identifier")
12local errComma = newError("expecting ','")
13
14local g = m.P{
15 "S",
16 S = m.Lc(m.Lc(m.V"Id" * m.V"List", m.V"ErrId", errId),
17 m.V"ErrComma", errComma),
18 List = -m.P(1) + (m.V"Comma" + m.T(errComma)) * (m.V"Id" + m.T(errId)) * m.V"List",
19 Id = m.V"Sp" * m.R'az'^1,
20 Comma = m.V"Sp" * ",",
21 Sp = m.S" \n\t"^0,
22 ErrId = m.Cc(errId) / terror,
23 ErrComma = m.Cc(errComma) / terror
24}
25
26print(m.match(g, "one,two"))
27print(m.match(g, "one two"))
28print(m.match(g, "one,\n two,\nthree,"))
diff --git a/examples/listIdCatchRe.lua b/examples/listIdCatchRe.lua
deleted file mode 100644
index 8971191..0000000
--- a/examples/listIdCatchRe.lua
+++ /dev/null
@@ -1,34 +0,0 @@
1local re = require'relabel'
2
3local terror = {}
4
5local function newError(l, msg)
6 table.insert(terror, { l = l, msg = msg } )
7end
8
9newError("errId", "Error: expecting an identifier")
10newError("errComma", "Error: expecting ','")
11
12local labelCode = {}
13local labelMsg = {}
14for k, v in ipairs(terror) do
15 labelCode[v.l] = k
16 labelMsg[v.l] = v.msg
17end
18
19re.setlabels(labelCode)
20
21local p = re.compile([[
22 S <- Id List /{errId} ErrId /{errComma} ErrComma
23 List <- !. / Comma Id List
24 Id <- [a-z]+ / %{errId}
25 Comma <- ',' / %{errComma}
26 ErrId <- '' -> errId
27 ErrComma <- '' -> errComma
28]], labelMsg)
29
30print(p:match("a,b"))
31print(p:match("a b"))
32print(p:match(",b"))
33
34
diff --git a/examples/listIdRe1.lua b/examples/listIdRe1.lua
index d092566..3988a3b 100644
--- a/examples/listIdRe1.lua
+++ b/examples/listIdRe1.lua
@@ -1,10 +1,10 @@
1local re = require 'relabel' 1local re = require 'relabelrec'
2 2
3local g = re.compile[[ 3local g = re.compile[[
4 S <- Id List 4 S <- Id List
5 List <- !. / (',' / %{2}) (Id / %{1}) List 5 List <- !. / Comma Id List
6 Id <- Sp [a-z]+ 6 Id <- Sp [a-z]+ / %{2}
7 Comma <- Sp ',' 7 Comma <- Sp ',' / %{3}
8 Sp <- %s* 8 Sp <- %s*
9]] 9]]
10 10
diff --git a/examples/listIdRe2.lua b/examples/listIdRe2.lua
index fe30535..6bab6ba 100644
--- a/examples/listIdRe2.lua
+++ b/examples/listIdRe2.lua
@@ -1,4 +1,4 @@
1local re = require 'relabel' 1local re = require 'relabelrec'
2 2
3local errinfo = { 3local errinfo = {
4 {"errUndef", "undefined"}, 4 {"errUndef", "undefined"},
@@ -18,23 +18,54 @@ re.setlabels(labels)
18 18
19local g = re.compile[[ 19local g = re.compile[[
20 S <- Id List 20 S <- Id List
21 List <- !. / (',' / %{errComma}) (Id / %{errId}) List 21 List <- !. / Comma Id List
22 Id <- Sp [a-z]+ 22 Id <- Sp {[a-z]+} / %{errId}
23 Comma <- Sp ',' 23 Comma <- Sp ',' / %{errComma}
24 Sp <- %s* 24 Sp <- %s*
25]] 25]]
26 26
27function mymatch (g, s) 27local errors
28 local r, e, sfail = g:match(s) 28
29 if not r then 29function recorderror (subject, pos, label)
30 local line, col = re.calcline(s, #s - #sfail) 30 local line, col = re.calcline(subject, pos)
31 local msg = "Error at line " .. line .. " (col " .. col .. "): " 31 table.insert(errors, { line = line, col = col, msg = errmsgs[labels[label]] })
32 return r, msg .. errmsgs[e] .. " before '" .. sfail .. "'" 32 return true
33 end 33end
34 return r 34
35function sync (p)
36 return '( !(' .. p .. ') .)*'
35end 37end
36 38
37print(mymatch(g, "one,two")) 39local grec = re.compile(
38print(mymatch(g, "one two")) 40 "S <- %g //{errComma} ErrComma //{errId} ErrId" .. "\n" ..
39print(mymatch(g, "one,\n two,\nthree,")) 41 "ErrComma <- ('' -> 'errComma' => recorderror) " .. sync('[a-z]+') .. "\n" ..
42 "ErrId <- ('' -> 'errId' => recorderror) " .. sync('","') .. "-> default"
43 , {g = g, recorderror = recorderror, default = "NONE"})
40 44
45function mymatch (g, s)
46 errors = {}
47 subject = s
48 io.write("Input: ", s, "\n")
49 local r = { g:match(s) }
50 io.write("Captures (separated by ';'): ")
51 for k, v in pairs(r) do
52 io.write(v .. "; ")
53 end
54 io.write("\nSyntactic errors found: " .. #errors)
55 if #errors > 0 then
56 io.write("\n")
57 local out = {}
58 for i, err in ipairs(errors) do
59 local msg = "Error at line " .. err.line .. " (col " .. err.col .. "): " .. err.msg
60 table.insert(out, msg)
61 end
62 io.write(table.concat(out, "\n"))
63 end
64 print("\n")
65 return r
66end
67
68mymatch(grec, "one,two")
69mymatch(grec, "one two three")
70mymatch(grec, "1,\n two, \n3,")
71mymatch(grec, "one\n two123, \nthree,")
diff --git a/examples/recovery.lua b/examples/recovery.lua
deleted file mode 100644
index 3272ae7..0000000
--- a/examples/recovery.lua
+++ /dev/null
@@ -1,134 +0,0 @@
1local lpeg = require"lpeglabel"
2
3local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V
4local C, Cc, Ct, Cmt = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt
5local T, Lc = lpeg.T, lpeg.Lc
6
7-- The `labels` table contains the list of labels that we will be using
8-- as well as the corresponding error message for each label, which will
9-- be used in our error reporting later on.
10local labels = {
11 {"NoExp", "no expression found"},
12 {"Extra", "extra characters found after the expression"},
13 {"ExpTerm", "expected a term after the operator"},
14 {"ExpExp", "expected an expression after the parenthesis"},
15 {"MisClose", "missing a closing ')' after the expression"},
16}
17
18-- The `labelindex` function gives us the index of a label in the
19-- `labels` table, which serves as the integer representation of the label.
20-- We need this because LPegLabel requires us to use integers for the labels.
21local function labelindex(labname)
22 for i, elem in ipairs(labels) do
23 if elem[1] == labname then
24 return i
25 end
26 end
27 error("could not find label: " .. labname)
28end
29
30-- The `errors` table will hold the list of errors recorded during parsing
31local errors = {}
32
33-- The `expect` function takes a pattern and a label and returns a pattern
34-- that throws the specified label if the original pattern fails to match.
35-- Before throwing the label, it records the label to be thrown along with
36-- the position of the failure (index in input string) into the `errors` table.
37local function expect(patt, labname)
38 local i = labelindex(labname)
39 function recorderror(input, pos)
40 table.insert(errors, {i, pos})
41 return true
42 end
43 return patt + Cmt("", recorderror) * T(i)
44end
45
46local num = R("09")^1 / tonumber
47local op = S("+-*/")
48
49-- The `compute` function takes an alternating list of numbers and
50-- operators and computes the result of applying the operations
51-- to the numbers in a left to right order (no operator precedence).
52local function compute(tokens)
53 local result = tokens[1]
54 for i = 2, #tokens, 2 do
55 if tokens[i] == '+' then
56 result = result + tokens[i+1]
57 elseif tokens[i] == '-' then
58 result = result - tokens[i+1]
59 elseif tokens[i] == '*' then
60 result = result * tokens[i+1]
61 elseif tokens[i] == '/' then
62 result = result / tokens[i+1]
63 else
64 error('unknown operation: ' .. tokens[i])
65 end
66 end
67 return result
68end
69
70-- Our grammar is a simple arithmetic expression of integers that
71-- does not take operator precedence into account but allows grouping
72-- via parenthesis. We have incorporated some error recovery startegies
73-- to our grammar so that it may resume parsing even after encountering
74-- an error, which allows us to report more errors.
75local g = P {
76 "Exp",
77 Exp = Ct(V"Term" * (C(op) * V"OpRecov")^0) / compute;
78 -- `OpRecov` handles missing terms/operands by returning a dummy (zero).
79 OpRecov = Lc(V"Operand", Cc(0), labelindex("ExpTerm"));
80 Operand = expect(V"Term", "ExpTerm");
81 Term = num + V"Group";
82 -- `Group` handles missing closing parenthesis by simply ignoring it.
83 -- Like all the others, the error is still recorded of course.
84 Group = "(" * V"InnerExp" * Lc(expect(")", "MisClose"), P"", labelindex("MisClose"));
85 -- `InnerExp` handles missing expressions by skipping to the next closing
86 -- parenthesis. A dummy (zero) is returned in place of the expression.
87 InnerExp = Lc(expect(V"Exp", "ExpExp"), (P(1) - ")")^0 * Cc(0), labelindex("ExpExp"));
88}
89
90g = expect(g, "NoExp") * expect(-P(1), "Extra")
91
92-- The `eval` function takes an input string to match against the grammar
93-- we've just defined. If the input string matches, then the result of the
94-- computation is returned, otherwise we return the error messages and
95-- positions of all the failures encountered.
96local function eval(input)
97 local result, label, suffix = g:match(input)
98 if #errors == 0 then
99 return result
100 else
101 local out = {}
102 for i, err in ipairs(errors) do
103 local pos = err[2]
104 local msg = labels[err[1]][2]
105 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
106 end
107 errors = {}
108 return nil, table.concat(out, "\n")
109 end
110end
111
112print(eval "98-76*(54/32)")
113--> 37.125
114
115print(eval "(1+1-1*2/2")
116--> syntax error: missing a closing ')' after the expression (at index 11)
117
118print(eval "(1+)-1*(2/2)")
119--> syntax error: expected a term after the operator (at index 4)
120
121print(eval "(1+1)-1*(/2)")
122--> syntax error: expected an expression after the parenthesis (at index 10)
123
124print(eval "1+(1-(1*2))/2x")
125--> syntax error: extra chracters found after the expression (at index 14)
126
127print(eval "-1+(1-(1*2))/2")
128--> syntax error: no expression found (at index 1)
129
130print(eval "(1+1-1*(2/2+)-():")
131--> syntax error: expected a term after the operator (at index 13)
132--> syntax error: expected an expression after the parenthesis (at index 16)
133--> syntax error: missing a closing ')' after the expression (at index 17)
134--> syntax error: extra characters found after the expression (at index 17)
diff --git a/examples/recoveryOpFail.lua b/examples/recoveryOpFail.lua
deleted file mode 100644
index 6ddc6a2..0000000
--- a/examples/recoveryOpFail.lua
+++ /dev/null
@@ -1,105 +0,0 @@
1local lpeg = require"lpeglabel"
2
3local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V
4local C, Cc, Ct, Cmt, Carg = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt, lpeg.Carg
5local T, Lc, Rec = lpeg.T, lpeg.Lc, lpeg.Rec
6
7local labels = {
8 {"NoExp", "no expression found"},
9 {"Extra", "extra characters found after the expression"},
10 {"ExpTerm", "expected a term after the operator"},
11 {"ExpExp", "expected an expression after the parenthesis"},
12 {"MisClose", "missing a closing ')' after the expression"},
13}
14
15local function labelindex(labname)
16 for i, elem in ipairs(labels) do
17 if elem[1] == labname then
18 return i
19 end
20 end
21 error("could not find label: " .. labname)
22end
23
24local function expect(patt, labname, recpatt)
25 local i = labelindex(labname)
26 local function recorderror(input, pos, errors)
27 table.insert(errors, {i, pos})
28 return true
29 end
30 if not recpatt then recpatt = P"" end
31 return Rec(patt, Cmt(Carg(1), recorderror) * recpatt)
32end
33
34local num = R("09")^1 / tonumber
35local op = S("+-*/")
36
37local function compute(tokens)
38 local result = tokens[1]
39 for i = 2, #tokens, 2 do
40 if tokens[i] == '+' then
41 result = result + tokens[i+1]
42 elseif tokens[i] == '-' then
43 result = result - tokens[i+1]
44 elseif tokens[i] == '*' then
45 result = result * tokens[i+1]
46 elseif tokens[i] == '/' then
47 result = result / tokens[i+1]
48 else
49 error('unknown operation: ' .. tokens[i])
50 end
51 end
52 return result
53end
54
55
56local g = P {
57 "Exp",
58 Exp = Ct(V"Term" * (C(op) * V"Operand")^0) / compute;
59 Operand = expect(V"Term", "ExpTerm", Cc(0));
60 Term = num + V"Group";
61 Group = "(" * V"InnerExp" * expect(")", "MisClose");
62 InnerExp = expect(V"Exp", "ExpExp", (P(1) - ")")^0 * Cc(0));
63}
64
65g = expect(g, "NoExp", P(1)^0) * expect(-P(1), "Extra")
66
67local function eval(input)
68 local errors = {}
69 local result, label, suffix = g:match(input, 1, errors)
70 if #errors == 0 then
71 return result
72 else
73 local out = {}
74 for i, err in ipairs(errors) do
75 local pos = err[2]
76 local msg = labels[err[1]][2]
77 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
78 end
79 return nil, table.concat(out, "\n")
80 end
81end
82
83print(eval "98-76*(54/32)")
84--> 37.125
85
86print(eval "(1+1-1*2/2")
87--> syntax error: missing a closing ')' after the expression (at index 11)
88
89print(eval "(1+)-1*(2/2)")
90--> syntax error: expected a term after the operator (at index 4)
91
92print(eval "(1+1)-1*(/2)")
93--> syntax error: expected an expression after the parenthesis (at index 10)
94
95print(eval "1+(1-(1*2))/2x")
96--> syntax error: extra chracters found after the expression (at index 14)
97
98print(eval "-1+(1-(1*2))/2")
99--> syntax error: no expression found (at index 1)
100
101print(eval "(1+1-1*(2/2+)-():")
102--> syntax error: expected a term after the operator (at index 13)
103--> syntax error: expected an expression after the parenthesis (at index 16)
104--> syntax error: missing a closing ')' after the expression (at index 17)
105--> syntax error: extra characters found after the expression (at index 17)
diff --git a/examples/recoveryOpLab.lua b/examples/recoveryOpLab.lua
deleted file mode 100644
index 6697f8b..0000000
--- a/examples/recoveryOpLab.lua
+++ /dev/null
@@ -1,107 +0,0 @@
1local lpeg = require"lpeglabel"
2
3local R, S, P, V = lpeg.R, lpeg.S, lpeg.P, lpeg.V
4local C, Cc, Ct, Cmt = lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.Cmt
5local T, Lc, Rec = lpeg.T, lpeg.Lc, lpeg.Rec
6
7local labels = {
8 {"NoExp", "no expression found"},
9 {"Extra", "extra characters found after the expression"},
10 {"ExpTerm", "expected a term after the operator"},
11 {"ExpExp", "expected an expression after the parenthesis"},
12 {"MisClose", "missing a closing ')' after the expression"},
13}
14
15local function labelindex(labname)
16 for i, elem in ipairs(labels) do
17 if elem[1] == labname then
18 return i
19 end
20 end
21 error("could not find label: " .. labname)
22end
23
24local errors = {}
25
26local function expect(patt, labname)
27 local i = labelindex(labname)
28 function recorderror(input, pos)
29 table.insert(errors, {i, pos})
30 return true
31 end
32 return patt + Cmt("", recorderror) * T(i)
33end
34
35local num = R("09")^1 / tonumber
36local op = S("+-*/")
37
38local function compute(tokens)
39 local result = tokens[1]
40 for i = 2, #tokens, 2 do
41 if tokens[i] == '+' then
42 result = result + tokens[i+1]
43 elseif tokens[i] == '-' then
44 result = result - tokens[i+1]
45 elseif tokens[i] == '*' then
46 result = result * tokens[i+1]
47 elseif tokens[i] == '/' then
48 result = result / tokens[i+1]
49 else
50 error('unknown operation: ' .. tokens[i])
51 end
52 end
53 return result
54end
55
56
57local g = P {
58 "Exp",
59 Exp = Ct(V"Term" * (C(op) * V"OpRecov")^0) / compute;
60 OpRecov = Rec(V"Operand", Cc(0), labelindex("ExpTerm"));
61 Operand = expect(V"Term", "ExpTerm");
62 Term = num + Rec(V"Group", P"", labelindex("MisClose"));
63 Group = "(" * Rec(V"InnerExp", (P(1) - ")")^0 * Cc(0), labelindex("ExpExp")) * expect(")", "MisClose");
64 InnerExp = expect(V"Exp", "ExpExp");
65}
66
67g = expect(g, "NoExp") * expect(-P(1), "Extra")
68
69local function eval(input)
70 local result, label, suffix = g:match(input)
71 if #errors == 0 then
72 return result
73 else
74 local out = {}
75 for i, err in ipairs(errors) do
76 local pos = err[2]
77 local msg = labels[err[1]][2]
78 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
79 end
80 errors = {}
81 return nil, table.concat(out, "\n")
82 end
83end
84
85print(eval "98-76*(54/32)")
86--> 37.125
87
88print(eval "(1+1-1*2/2")
89--> syntax error: missing a closing ')' after the expression (at index 11)
90
91print(eval "(1+)-1*(2/2)")
92--> syntax error: expected a term after the operator (at index 4)
93
94print(eval "(1+1)-1*(/2)")
95--> syntax error: expected an expression after the parenthesis (at index 10)
96
97print(eval "1+(1-(1*2))/2x")
98--> syntax error: extra chracters found after the expression (at index 14)
99
100print(eval "-1+(1-(1*2))/2")
101--> syntax error: no expression found (at index 1)
102
103print(eval "(1+1-1*(2/2+)-():")
104--> syntax error: expected a term after the operator (at index 13)
105--> syntax error: expected an expression after the parenthesis (at index 16)
106--> syntax error: missing a closing ')' after the expression (at index 17)
107--> syntax error: extra characters found after the expression (at index 17)
diff --git a/examples/tiny.lua b/examples/tiny.lua
index 99c3144..784e031 100644
--- a/examples/tiny.lua
+++ b/examples/tiny.lua
@@ -1,4 +1,4 @@
1local re = require 'relabel' 1local re = require 'relabelrec'
2 2
3local terror = {} 3local terror = {}
4 4
@@ -25,21 +25,6 @@ newError("errFactor", "Error: expected '(', ID, or number after '*' or '/'")
25newError("errExpFac", "Error: expected expression after '('") 25newError("errExpFac", "Error: expected expression after '('")
26newError("errClosePar", "Error: expected ')' after expression") 26newError("errClosePar", "Error: expected ')' after expression")
27 27
28local line
29
30local function incLine()
31 line = line + 1
32 return true
33end
34
35local function countLine(s, i)
36 line = 1
37 local p = re.compile([[
38 S <- (%nl -> incLine / .)*
39 ]], { incLine = incLine})
40 p:match(s:sub(1, i))
41 return true
42end
43 28
44local labelCode = {} 29local labelCode = {}
45for k, v in ipairs(terror) do 30for k, v in ipairs(terror) do
@@ -48,7 +33,7 @@ end
48 33
49re.setlabels(labelCode) 34re.setlabels(labelCode)
50 35
51local g = re.compile([[ 36local g = re.compile[[
52 Tiny <- CmdSeq 37 Tiny <- CmdSeq
53 CmdSeq <- (Cmd (SEMICOLON / ErrSemi)) (Cmd (SEMICOLON / ErrSemi))* 38 CmdSeq <- (Cmd (SEMICOLON / ErrSemi)) (Cmd (SEMICOLON / ErrSemi))*
54 Cmd <- IfCmd / RepeatCmd / ReadCmd / WriteCmd / AssignCmd 39 Cmd <- IfCmd / RepeatCmd / ReadCmd / WriteCmd / AssignCmd
@@ -61,25 +46,24 @@ local g = re.compile([[
61 SimpleExp <- Term ((ADD / SUB) (Term / ErrTerm))* 46 SimpleExp <- Term ((ADD / SUB) (Term / ErrTerm))*
62 Term <- Factor ((MUL / DIV) (Factor / ErrFactor))* 47 Term <- Factor ((MUL / DIV) (Factor / ErrFactor))*
63 Factor <- OPENPAR (Exp / ErrExpFac) (CLOSEPAR / ErrClosePar) / NUMBER / NAME 48 Factor <- OPENPAR (Exp / ErrExpFac) (CLOSEPAR / ErrClosePar) / NUMBER / NAME
64 ErrSemi <- ErrCount %{errSemi} 49 ErrSemi <- %{errSemi}
65 ErrExpIf <- ErrCount %{errExpIf} 50 ErrExpIf <- %{errExpIf}
66 ErrThen <- ErrCount %{errThen} 51 ErrThen <- %{errThen}
67 ErrCmdSeq1 <- ErrCount %{errCmdSeq1} 52 ErrCmdSeq1 <- %{errCmdSeq1}
68 ErrCmdSeq2 <- ErrCount %{errCmdSeq2} 53 ErrCmdSeq2 <- %{errCmdSeq2}
69 ErrEnd <- ErrCount %{errEnd} 54 ErrEnd <- %{errEnd}
70 ErrCmdSeqRep <- ErrCount %{errCmdSeqRep} 55 ErrCmdSeqRep <- %{errCmdSeqRep}
71 ErrUntil <- ErrCount %{errUntil} 56 ErrUntil <- %{errUntil}
72 ErrExpRep <- ErrCount %{errExpRep} 57 ErrExpRep <- %{errExpRep}
73 ErrAssignOp <- ErrCount %{errAssignOp} 58 ErrAssignOp <- %{errAssignOp}
74 ErrExpAssign <- ErrCount %{errExpAssign} 59 ErrExpAssign <- %{errExpAssign}
75 ErrReadName <- ErrCount %{errReadName} 60 ErrReadName <- %{errReadName}
76 ErrWriteExp <- ErrCount %{errWriteExp} 61 ErrWriteExp <- %{errWriteExp}
77 ErrSimpExp <- ErrCount %{errSimpExp} 62 ErrSimpExp <- %{errSimpExp}
78 ErrTerm <- ErrCount %{errTerm} 63 ErrTerm <- %{errTerm}
79 ErrFactor <- ErrCount %{errFactor} 64 ErrFactor <- %{errFactor}
80 ErrExpFac <- ErrCount %{errExpFac} 65 ErrExpFac <- %{errExpFac}
81 ErrClosePar <- ErrCount %{errClosePar} 66 ErrClosePar <- %{errClosePar}
82 ErrCount <- '' => countLine
83 ADD <- Sp '+' 67 ADD <- Sp '+'
84 ASSIGNMENT <- Sp ':=' 68 ASSIGNMENT <- Sp ':='
85 CLOSEPAR <- Sp ')' 69 CLOSEPAR <- Sp ')'
@@ -102,12 +86,17 @@ local g = re.compile([[
102 WRITE <- Sp 'write' 86 WRITE <- Sp 'write'
103 RESERVED <- (IF / ELSE / END / READ / REPEAT / THEN / UNTIL / WRITE) ![a-z]+ 87 RESERVED <- (IF / ELSE / END / READ / REPEAT / THEN / UNTIL / WRITE) ![a-z]+
104 Sp <- %s* 88 Sp <- %s*
105]], { countLine = countLine }) 89]]
106 90
107 91
108local function printError(n, e) 92local function mymatch(g, s)
109 assert(n == nil) 93 local r, e, sfail = g:match(s)
110 print("Line " .. line .. ": " .. terror[e].msg) 94 if not r then
95 local line, col = re.calcline(s, #s - #sfail)
96 local msg = "Error at line " .. line .. " (col " .. col .. "): "
97 return r, msg .. terror[e].msg
98 end
99 return r
111end 100end
112 101
113local s = [[ 102local s = [[
@@ -118,7 +107,7 @@ repeat
118 n := n - 1 107 n := n - 1
119until (n < 1); 108until (n < 1);
120write f;]] 109write f;]]
121printError(g:match(s)) 110print(mymatch(g, s))
122 111
123s = [[ 112s = [[
124n := 5; 113n := 5;
@@ -128,14 +117,14 @@ repeat
128 n := n - 1; 117 n := n - 1;
129until (n < 1); 118until (n < 1);
130read ;]] 119read ;]]
131printError(g:match(s)) 120print(mymatch(g, s))
132 121
133s = [[ 122s = [[
134if a < 1 then 123if a < 1 then
135 b := 2; 124 b := 2;
136else 125else
137 b := 3;]] 126 b := 3;]]
138printError(g:match(s)) 127print(mymatch(g, s))
139 128
140s = [[ 129s = [[
141n := 5; 130n := 5;
@@ -145,7 +134,7 @@ repeat
145 n := n - 1; 134 n := n - 1;
146untill (n < 1); 135untill (n < 1);
147]] 136]]
148printError(g:match(s)) 137print(mymatch(g, s))
149 138
150s = [[ 139s = [[
151n := 5; 140n := 5;
@@ -155,9 +144,8 @@ repeat
155 n := n - 1; 144 n := n - 1;
1563 (n < 1); 1453 (n < 1);
157]] 146]]
158printError(g:match(s)) 147print(mymatch(g, s))
159
160printError(g:match("a : 2"))
161printError(g:match("a := (2"))
162 148
149print(mymatch(g, "a : 2"))
150print(mymatch(g, "a := (2"))
163 151
diff --git a/examples/typedlua/test.lua b/examples/typedlua/test.lua
index ed4e7a1..95474ba 100755
--- a/examples/typedlua/test.lua
+++ b/examples/typedlua/test.lua
@@ -401,15 +401,18 @@ assert(m == e)
401-- unfinished comments 401-- unfinished comments
402 402
403s = [=[ 403s = [=[
404--[[ testing 404--[[
405
406testing
405unfinished 407unfinished
408
406comment 409comment
407]=] 410 ]=]
408--[=[ 411--[=[
409test.lua:3:1: syntax error, unexpected 'comment', expecting '=', ',', 'String', '{', '(', ':', '[', '.' 412test.lua:3:1: syntax error, unexpected 'comment', expecting '=', ',', 'String', '{', '(', ':', '[', '.'
410]=] 413]=]
411e = [=[ 414e = [=[
412test.lua:1:1: unfinished long comment 415test.lua:1:2: unfinished long comment
413]=] 416]=]
414 417
415r, m = parse(s) 418r, m = parse(s)
diff --git a/examples/typedlua/tllexer.lua b/examples/typedlua/tllexer.lua
index 6517ba5..d6033ec 100644
--- a/examples/typedlua/tllexer.lua
+++ b/examples/typedlua/tllexer.lua
@@ -1,6 +1,6 @@
1local tllexer = {} 1local tllexer = {}
2 2
3local lpeg = require "lpeglabel" 3local lpeg = require "lpeglabelrec"
4lpeg.locale(lpeg) 4lpeg.locale(lpeg)
5 5
6local tlerror = require "tlerror" 6local tlerror = require "tlerror"
@@ -9,10 +9,6 @@ function tllexer.try (pat, label)
9 return pat + lpeg.T(tlerror.labels[label]) 9 return pat + lpeg.T(tlerror.labels[label])
10end 10end
11 11
12function tllexer.catch (pat, label)
13 return lpeg.Lc(pat, lpeg.P(false), tlerror.labels[label])
14end
15
16local function setffp (s, i, t, n) 12local function setffp (s, i, t, n)
17 if not t.ffp or i > t.ffp then 13 if not t.ffp or i > t.ffp then
18 t.ffp = i 14 t.ffp = i
@@ -45,7 +41,10 @@ local CloseEQ = lpeg.Cmt(Close * lpeg.Cb("init"),
45local LongString = Open * (lpeg.P(1) - CloseEQ)^0 * tllexer.try(Close, "LongString") / 41local LongString = Open * (lpeg.P(1) - CloseEQ)^0 * tllexer.try(Close, "LongString") /
46 function (s, o) return s end 42 function (s, o) return s end
47 43
48local Comment = lpeg.Lc(lpeg.P("--") * LongString / function () return end, 44local LongStringCm1 = Open * (lpeg.P(1) - CloseEQ)^0 * Close /
45 function (s, o) return s end
46
47local Comment = lpeg.Rec(lpeg.P"--" * #Open * (LongStringCm1 / function() return end + lpeg.T(tlerror.labels["LongString"])),
49 lpeg.T(tlerror.labels["LongComment"]), tlerror.labels["LongString"]) + 48 lpeg.T(tlerror.labels["LongComment"]), tlerror.labels["LongString"]) +
50 lpeg.P("--") * (lpeg.P(1) - lpeg.P("\n"))^0 49 lpeg.P("--") * (lpeg.P(1) - lpeg.P("\n"))^0
51 50
diff --git a/examples/typedlua/tlparser.lua b/examples/typedlua/tlparser.lua
index a301fa6..fe4fd5e 100644
--- a/examples/typedlua/tlparser.lua
+++ b/examples/typedlua/tlparser.lua
@@ -1,6 +1,6 @@
1local tlparser = {} 1local tlparser = {}
2 2
3local lpeg = require "lpeglabel" 3local lpeg = require "lpeglabelrec"
4lpeg.locale(lpeg) 4lpeg.locale(lpeg)
5 5
6local tllexer = require "tllexer" 6local tllexer = require "tllexer"