aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergio Queiroz <sqmedeiros@gmail.com>2016-11-29 18:38:55 -0300
committerSergio Queiroz <sqmedeiros@gmail.com>2016-11-29 18:38:55 -0300
commita4bdec34353ad1849f99e6ab0e5f2ad5e74c83b1 (patch)
treea0654a2c516b01d39dbf4b0b978d8207eb045c30
parente7e17699870f0bd6ba43b4e946297fb581d28b48 (diff)
downloadlpeglabel-a4bdec34353ad1849f99e6ab0e5f2ad5e74c83b1.tar.gz
lpeglabel-a4bdec34353ad1849f99e6ab0e5f2ad5e74c83b1.tar.bz2
lpeglabel-a4bdec34353ad1849f99e6ab0e5f2ad5e74c83b1.zip
New example shows how to build recovery grammar semiautomatically
-rw-r--r--examples/expressionRecAut.lua132
-rw-r--r--examples/expressionRecovery.lua3
2 files changed, 134 insertions, 1 deletions
diff --git a/examples/expressionRecAut.lua b/examples/expressionRecAut.lua
new file mode 100644
index 0000000..e098078
--- /dev/null
+++ b/examples/expressionRecAut.lua
@@ -0,0 +1,132 @@
1local m = require"lpeglabelrec"
2local re = require"relabelrec"
3
4local R, S, P, V = m.R, m.S, m.P, m.V
5local C, Cc, Ct, Cmt = m.C, m.Cc, m.Ct, m.Cmt
6local T, Rec = m.T, m.Rec
7
8local num = R("09")^1 / tonumber
9local op = S("+-")
10
11local labels = {}
12local nlabels = 0
13
14local function newError(lab, msg, psync, pcap)
15 nlabels = nlabels + 1
16 psync = psync or m.P(-1)
17 pcap = pcap or m.P""
18 labels[lab] = { id = nlabels, msg = msg, psync = psync, pcap = pcap }
19end
20
21newError("ExpTermFirst", "expected an expression", op + ")", m.Cc(1000))
22newError("ExpTermOp", "expected a term after the operator", op + ")", m.Cc(1000))
23newError("MisClose", "missing a closing ')' after the expression", m.P")")
24newError("Extra", "extra characters found after the expression")
25
26local errors, subject
27
28local function expect(patt, labname)
29 local i = labels[labname].id
30 return patt + T(i)
31end
32
33local function compute(tokens)
34 local result = tokens[1]
35 for i = 2, #tokens, 2 do
36 if 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"OperandFirst" * (C(op) * V"Operand")^0) / compute,
50 OperandFirst = expect(V"Term", "ExpTermFirst"),
51 Operand = expect(V"Term", "ExpTermOp"),
52 Term = num + V"Group",
53 Group = "(" * V"Exp" * expect(")", "MisClose"),
54}
55
56function recorderror(pos, lab)
57 local line, col = re.calcline(subject, pos)
58 table.insert(errors, { line = line, col = col, msg = labels[lab].msg })
59end
60
61function record (labname)
62 return (m.Cp() * m.Cc(labname)) / recorderror
63end
64
65function sync (p)
66 return (-p * m.P(1))^0
67end
68
69function defaultValue (p)
70 return p or m.Cc(1000)
71end
72
73local recg2 = g
74for k, v in pairs(labels) do
75 recg2 = Rec(recg2, record(k) * sync(v.psync) * v.pcap, v.id)
76end
77
78local recg = P {
79 "S",
80 S = Rec(V"A", V"ErrExpTermFirst", labels["ExpTermFirst"].id), -- default value is 0
81 A = Rec(V"Sg", V"ErrExpTermOp", labels["ExpTermOp"].id),
82 Sg = Rec(g, V"ErrMisClose", labels["MisClose"].id),
83 ErrExpTermFirst = record("ExpTermFirst") * sync(op + ")") * defaultValue(),
84 ErrExpTermOp = record("ExpTermOp") * sync(op + ")") * defaultValue(),
85 ErrMisClose = record("MisClose") * sync(P")") * defaultValue(m.P""),
86}
87
88
89local function eval(input)
90 errors = {}
91 subject = input
92 local result, label, suffix = recg2:match(input)
93 if #errors > 0 then
94 local out = {}
95 for i, err in ipairs(errors) do
96 local pos = err.col
97 local msg = err.msg
98 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
99 end
100 print(table.concat(out, "\n"))
101 end
102 return result
103end
104
105print(eval "90-70*5")
106--> 20
107
108print(eval "2+")
109--> 2 + 0
110
111print(eval "-2")
112--> 0 - 2
113
114print(eval "1+3+-9")
115--> 1 + 3 + [0] - 9
116
117print(eval "1+()3+")
118--> 1 + ([0]) [+] 3 + [0]
119
120print(eval "8-(2+)-5")
121--> 8 - (2 + [0]) - 5
122
123print(eval "()")
124
125print(eval "")
126
127print(eval "1+()+")
128
129print(eval "1+(")
130
131print(eval "3)")
132
diff --git a/examples/expressionRecovery.lua b/examples/expressionRecovery.lua
index a4a3288..c5cbcca 100644
--- a/examples/expressionRecovery.lua
+++ b/examples/expressionRecovery.lua
@@ -91,7 +91,6 @@ local function eval(input)
91 for i, err in ipairs(errors) do 91 for i, err in ipairs(errors) do
92 local pos = err.col 92 local pos = err.col
93 local msg = err.msg 93 local msg = err.msg
94 print("sub", subject)
95 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")") 94 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
96 end 95 end
97 print(table.concat(out, "\n")) 96 print(table.concat(out, "\n"))
@@ -123,5 +122,7 @@ print(eval "")
123 122
124print(eval "1+()+") 123print(eval "1+()+")
125 124
125print(eval "1+(")
126
126print(eval "3)") 127print(eval "3)")
127 128