diff options
-rw-r--r-- | examples/expect.lua | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/examples/expect.lua b/examples/expect.lua index 2b7e904..cb68d38 100644 --- a/examples/expect.lua +++ b/examples/expect.lua | |||
@@ -2,6 +2,9 @@ local lpeg = require"lpeglabel" | |||
2 | 2 | ||
3 | local R, S, P, V, C, Ct, T = lpeg.R, lpeg.S, lpeg.P, lpeg.V, lpeg.C, lpeg.Ct, lpeg.T | 3 | local R, S, P, V, C, Ct, T = lpeg.R, lpeg.S, lpeg.P, lpeg.V, lpeg.C, lpeg.Ct, lpeg.T |
4 | 4 | ||
5 | -- The `labels` table contains the list of labels that we will be using | ||
6 | -- as well as the corresponding error message for each label, which will | ||
7 | -- be used in our error reporting later on. | ||
5 | local labels = { | 8 | local labels = { |
6 | {"NoExp", "no expression found"}, | 9 | {"NoExp", "no expression found"}, |
7 | {"Extra", "extra characters found after the expression"}, | 10 | {"Extra", "extra characters found after the expression"}, |
@@ -10,6 +13,11 @@ local labels = { | |||
10 | {"MisClose", "missing a closing ')' after the expression"}, | 13 | {"MisClose", "missing a closing ')' after the expression"}, |
11 | } | 14 | } |
12 | 15 | ||
16 | -- The `expect` function takes a pattern and a label defined in | ||
17 | -- the `labels` table and returns a pattern that throws the specified | ||
18 | -- label if the original pattern fails to match. | ||
19 | -- Note: LPegLabel requires us to use integers for the labels, so we | ||
20 | -- use the index of the label in the `labels` table to represent it. | ||
13 | local function expect(patt, labname) | 21 | local function expect(patt, labname) |
14 | for i, elem in ipairs(labels) do | 22 | for i, elem in ipairs(labels) do |
15 | if elem[1] == labname then | 23 | if elem[1] == labname then |
@@ -23,6 +31,9 @@ end | |||
23 | local num = R("09")^1 / tonumber | 31 | local num = R("09")^1 / tonumber |
24 | local op = S("+-*/") | 32 | local op = S("+-*/") |
25 | 33 | ||
34 | -- The `compute` function takes an alternating list of numbers and | ||
35 | -- operators and computes the result of applying the operations | ||
36 | -- to the numbers in a left to right order (no operator precedence). | ||
26 | local function compute(tokens) | 37 | local function compute(tokens) |
27 | local result = tokens[1] | 38 | local result = tokens[1] |
28 | for i = 2, #tokens, 2 do | 39 | for i = 2, #tokens, 2 do |
@@ -41,6 +52,9 @@ local function compute(tokens) | |||
41 | return result | 52 | return result |
42 | end | 53 | end |
43 | 54 | ||
55 | -- Our grammar is a simple arithmetic expression of integers that | ||
56 | -- does not take operator precedence into account but allows grouping | ||
57 | -- via parenthesis. | ||
44 | local g = P { | 58 | local g = P { |
45 | "Exp", | 59 | "Exp", |
46 | Exp = Ct(V"Term" * (C(op) * expect(V"Term", "ExpTerm"))^0) / compute; | 60 | Exp = Ct(V"Term" * (C(op) * expect(V"Term", "ExpTerm"))^0) / compute; |
@@ -50,6 +64,10 @@ local g = P { | |||
50 | 64 | ||
51 | g = expect(g, "NoExp") * expect(-P(1), "Extra") | 65 | g = expect(g, "NoExp") * expect(-P(1), "Extra") |
52 | 66 | ||
67 | -- The `eval` function takes an input string to match against the grammar | ||
68 | -- we've just defined. If the input string matches, then the result of the | ||
69 | -- computation is returned, otherwise we return the error message and | ||
70 | -- position of the first failure encountered. | ||
53 | local function eval(input) | 71 | local function eval(input) |
54 | local result, label, suffix = g:match(input) | 72 | local result, label, suffix = g:match(input) |
55 | if result ~= nil then | 73 | if result ~= nil then |