aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSérgio Medeiros <sqmedeiros@gmail.com>2016-06-23 16:58:16 -0300
committerGitHub <noreply@github.com>2016-06-23 16:58:16 -0300
commit450cb2596448c19e672a30616bbd22d98b8c6588 (patch)
tree3779bee4290e37c6a86e9916e852dcc40680b0fb
parentb76d6a5bf919b4a7b6fd8f1ed3819da004fb6293 (diff)
parentc74eb058fe98d1d482954ad91a5e1b5805e225ff (diff)
downloadlpeglabel-lpeg-0.12.tar.gz
lpeglabel-lpeg-0.12.tar.bz2
lpeglabel-lpeg-0.12.zip
Merge pull request #9 from undecidabot/masterlpeg-0.12
Adding an example of LPegLabel with an "expect" function
-rw-r--r--examples/expect.md87
1 files changed, 87 insertions, 0 deletions
diff --git a/examples/expect.md b/examples/expect.md
new file mode 100644
index 0000000..d7d2d3e
--- /dev/null
+++ b/examples/expect.md
@@ -0,0 +1,87 @@
1Here's an example of an LPegLabel grammar that make its own function called
2'expect', which takes a pattern and a label as parameters and throws the label
3if the pattern fails to be matched. This function can be extended later on to
4record all errors encountered once error recovery is implemented.
5
6```lua
7local lpeg = require"lpeglabel"
8
9local R, S, P, V, C, Ct, T = lpeg.R, lpeg.S, lpeg.P, lpeg.V, lpeg.C, lpeg.Ct, lpeg.T
10
11local labels = {
12 {"NoExp", "no expression found"},
13 {"Extra", "extra characters found after the expression"},
14 {"ExpTerm", "expected a term after the operator"},
15 {"ExpExp", "expected an expression after the parenthesis"},
16 {"MisClose", "missing a closing ')' after the expression"},
17}
18
19local function expect(patt, labname)
20 for i, elem in ipairs(labels) do
21 if elem[1] == labname then
22 return patt + T(i)
23 end
24 end
25
26 error("could not find label: " .. labname)
27end
28
29local num = R("09")^1 / tonumber
30local op = S("+-*/")
31
32local function compute(tokens)
33 local result = tokens[1]
34 for i = 2, #tokens, 2 do
35 if tokens[i] == '+' then
36 result = result + tokens[i+1]
37 elseif tokens[i] == '-' then
38 result = result - tokens[i+1]
39 elseif tokens[i] == '*' then
40 result = result * tokens[i+1]
41 elseif tokens[i] == '/' then
42 result = result / tokens[i+1]
43 else
44 error('unknown operation: ' .. tokens[i])
45 end
46 end
47 return result
48end
49
50local g = P {
51 "Exp",
52 Exp = Ct(V"Term" * (C(op) * expect(V"Term", "ExpTerm"))^0) / compute;
53 Term = num + V"Group";
54 Group = "(" * expect(V"Exp", "ExpExp") * expect(")", "MisClose");
55}
56
57g = expect(g, "NoExp") * expect(-P(1), "Extra")
58
59local function eval(input)
60 local result, label, suffix = g:match(input)
61 if result ~= nil then
62 return result
63 else
64 local pos = input:len() - suffix:len() + 1
65 local msg = labels[label][2]
66 return nil, "syntax error: " .. msg .. " (at index " .. pos .. ")"
67 end
68end
69
70print(eval "98-76*(54/32)")
71--> 37.125
72
73print(eval "(1+1-1*2/2")
74--> syntax error: missing a closing ')' after the expression (at index 11)
75
76print(eval "(1+)-1*(2/2)")
77--> syntax error: expected a term after the operator (at index 4)
78
79print(eval "(1+1)-1*(/2)")
80--> syntax error: expected an expression after the parenthesis (at index 10)
81
82print(eval "1+(1-(1*2))/2x")
83--> syntax error: extra chracters found after the expression (at index 14)
84
85print(eval "-1+(1-(1*2))/2")
86--> syntax error: no expression found (at index 1)
87```