diff options
Diffstat (limited to 'examples/expect.lua')
| -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 |
