aboutsummaryrefslogtreecommitdiff
path: root/examples/recoveryOpFail.lua
diff options
context:
space:
mode:
Diffstat (limited to 'examples/recoveryOpFail.lua')
-rw-r--r--examples/recoveryOpFail.lua105
1 files changed, 0 insertions, 105 deletions
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)