diff options
author | Sergio Queiroz <sqmedeiros@gmail.com> | 2016-12-07 08:50:03 -0300 |
---|---|---|
committer | Sergio Queiroz <sqmedeiros@gmail.com> | 2016-12-07 08:50:03 -0300 |
commit | 2ea15094a1d4a9f422c983480aab7231951ee20e (patch) | |
tree | 119348d9249fa8bbc6ef3b5223cc12f34f179697 /examples/expRec.lua | |
parent | a4bdec34353ad1849f99e6ab0e5f2ad5e74c83b1 (diff) | |
download | lpeglabel-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.lua | 128 |
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 @@ | |||
1 | local m = require"lpeglabelrec" | ||
2 | local re = require"relabelrec" | ||
3 | |||
4 | local R, S, P, V = m.R, m.S, m.P, m.V | ||
5 | local C, Cc, Ct, Cmt = m.C, m.Cc, m.Ct, m.Cmt | ||
6 | local T, Rec = m.T, m.Rec | ||
7 | |||
8 | local labels = { | ||
9 | {"ExpTermFirst", "expected an expression"}, | ||
10 | {"ExpTermOp", "expected a term after the operator"}, | ||
11 | {"MisClose", "missing a closing ')' after the expression"}, | ||
12 | } | ||
13 | |||
14 | local 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) | ||
21 | end | ||
22 | |||
23 | local errors, subject | ||
24 | |||
25 | local function expect(patt, labname, recpatt) | ||
26 | local i = labelindex(labname) | ||
27 | return patt + T(i) | ||
28 | end | ||
29 | |||
30 | |||
31 | local num = R("09")^1 / tonumber | ||
32 | local op = S("+-") | ||
33 | |||
34 | local 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 | ||
46 | end | ||
47 | |||
48 | local 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 | |||
57 | function recorderror(pos, lab) | ||
58 | local line, col = re.calcline(subject, pos) | ||
59 | table.insert(errors, { line = line, col = col, msg = labels[lab][2] }) | ||
60 | end | ||
61 | |||
62 | function record (labname) | ||
63 | return (m.Cp() * m.Cc(labelindex(labname))) / recorderror | ||
64 | end | ||
65 | |||
66 | function sync (p) | ||
67 | return (-p * m.P(1))^0 | ||
68 | end | ||
69 | |||
70 | function defaultValue (p) | ||
71 | return p or m.Cc(1000) | ||
72 | end | ||
73 | |||
74 | local 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 | |||
85 | local 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 | ||
99 | end | ||
100 | |||
101 | print(eval "90-70*5") | ||
102 | --> 20 | ||
103 | |||
104 | print(eval "2+") | ||
105 | --> 2 + 0 | ||
106 | |||
107 | print(eval "-2") | ||
108 | --> 0 - 2 | ||
109 | |||
110 | print(eval "1+3+-9") | ||
111 | --> 1 + 3 + [0] - 9 | ||
112 | |||
113 | print(eval "1+()3+") | ||
114 | --> 1 + ([0]) [3 +] [0] | ||
115 | |||
116 | print(eval "8-(2+)-5") | ||
117 | --> 8 - (2 + [0]) - 5 | ||
118 | |||
119 | print(eval "()") | ||
120 | |||
121 | print(eval "") | ||
122 | |||
123 | print(eval "1+()+") | ||
124 | |||
125 | print(eval "1+(") | ||
126 | |||
127 | print(eval "3)") | ||
128 | |||