aboutsummaryrefslogtreecommitdiff
path: root/examples/expRec.lua
diff options
context:
space:
mode:
authorSergio Queiroz <sqmedeiros@gmail.com>2016-12-07 08:50:03 -0300
committerSergio Queiroz <sqmedeiros@gmail.com>2016-12-07 08:50:03 -0300
commit2ea15094a1d4a9f422c983480aab7231951ee20e (patch)
tree119348d9249fa8bbc6ef3b5223cc12f34f179697 /examples/expRec.lua
parenta4bdec34353ad1849f99e6ab0e5f2ad5e74c83b1 (diff)
downloadlpeglabel-2ea15094a1d4a9f422c983480aab7231951ee20e.tar.gz
lpeglabel-2ea15094a1d4a9f422c983480aab7231951ee20e.tar.bz2
lpeglabel-2ea15094a1d4a9f422c983480aab7231951ee20e.zip
Renaming files and removing example based on another version
Diffstat (limited to 'examples/expRec.lua')
-rw-r--r--examples/expRec.lua128
1 files changed, 128 insertions, 0 deletions
diff --git a/examples/expRec.lua b/examples/expRec.lua
new file mode 100644
index 0000000..c5cbcca
--- /dev/null
+++ b/examples/expRec.lua
@@ -0,0 +1,128 @@
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 labels = {
9 {"ExpTermFirst", "expected an expression"},
10 {"ExpTermOp", "expected a term after the operator"},
11 {"MisClose", "missing a closing ')' after the expression"},
12}
13
14local function labelindex(labname)
15 for i, elem in ipairs(labels) do
16 if elem[1] == labname then
17 return i
18 end
19 end
20 error("could not find label: " .. labname)
21end
22
23local errors, subject
24
25local function expect(patt, labname, recpatt)
26 local i = labelindex(labname)
27 return patt + T(i)
28end
29
30
31local num = R("09")^1 / tonumber
32local op = S("+-")
33
34local function compute(tokens)
35 local result = tokens[1]
36 for i = 2, #tokens, 2 do
37 if tokens[i] == '+' then
38 result = result + tokens[i+1]
39 elseif tokens[i] == '-' then
40 result = result - tokens[i+1]
41 else
42 error('unknown operation: ' .. tokens[i])
43 end
44 end
45 return result
46end
47
48local g = P {
49 "Exp",
50 Exp = Ct(V"OperandFirst" * (C(op) * V"Operand")^0) / compute,
51 OperandFirst = expect(V"Term", "ExpTermFirst"),
52 Operand = expect(V"Term", "ExpTermOp"),
53 Term = num + V"Group",
54 Group = "(" * V"Exp" * expect(")", "MisClose"),
55}
56
57function recorderror(pos, lab)
58 local line, col = re.calcline(subject, pos)
59 table.insert(errors, { line = line, col = col, msg = labels[lab][2] })
60end
61
62function record (labname)
63 return (m.Cp() * m.Cc(labelindex(labname))) / recorderror
64end
65
66function sync (p)
67 return (-p * m.P(1))^0
68end
69
70function defaultValue (p)
71 return p or m.Cc(1000)
72end
73
74local recg = P {
75 "S",
76 S = Rec(V"A", V"ErrExpTermFirst", labelindex("ExpTermFirst")), -- default value is 0
77 A = Rec(V"Sg", V"ErrExpTermOp", labelindex("ExpTermOp")),
78 Sg = Rec(g, V"ErrMisClose", labelindex("MisClose")),
79 ErrExpTermFirst = record("ExpTermFirst") * sync(op + ")") * defaultValue(),
80 ErrExpTermOp = record("ExpTermOp") * sync(op + ")") * defaultValue(),
81 ErrMisClose = record("MisClose") * sync(P")") * defaultValue(m.P""),
82}
83
84
85local function eval(input)
86 errors = {}
87 subject = input
88 local result, label, suffix = recg:match(input)
89 if #errors > 0 then
90 local out = {}
91 for i, err in ipairs(errors) do
92 local pos = err.col
93 local msg = err.msg
94 table.insert(out, "syntax error: " .. msg .. " (at index " .. pos .. ")")
95 end
96 print(table.concat(out, "\n"))
97 end
98 return result
99end
100
101print(eval "90-70*5")
102--> 20
103
104print(eval "2+")
105--> 2 + 0
106
107print(eval "-2")
108--> 0 - 2
109
110print(eval "1+3+-9")
111--> 1 + 3 + [0] - 9
112
113print(eval "1+()3+")
114--> 1 + ([0]) [3 +] [0]
115
116print(eval "8-(2+)-5")
117--> 8 - (2 + [0]) - 5
118
119print(eval "()")
120
121print(eval "")
122
123print(eval "1+()+")
124
125print(eval "1+(")
126
127print(eval "3)")
128