diff options
| author | 2021-12-23 17:41:22 -0500 | |
|---|---|---|
| committer | 2021-12-23 17:41:22 -0500 | |
| commit | f342c5e84ede465bc2393f0034cb09e9a9149c70 (patch) | |
| tree | f88b42f8d294e2a459f97c8bb7bf141db47cd27a | |
| parent | initial import (diff) | |
add math.lua example
| -rw-r--r-- | examples/math.lua | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/examples/math.lua b/examples/math.lua new file mode 100644 index 0000000..eed979b --- /dev/null +++ b/examples/math.lua @@ -0,0 +1,63 @@ +local patok = require 'patok' +local inspect = require 'inspect' +local pm = require 'piecemeal' + +local lexer = patok { + op = '[+*]', + digit = '%d+', + space = '%s+', +}() + +local lex = { + -- plus = pm.lexeme 'plus', + plus = pm.value '+', + times = pm.value '*', + digit = pm.postp(pm.lexeme 'digit', function(d) return tonumber(d.value) end), + space = pm.opt(pm.lexeme 'space') +} + +local function findnums(d, acc) + local out = acc or {} + for _, v in ipairs(d) do -- only ipairs to avoid triggering on tokens + if type(v) == 'number' then + table.insert(out, v) + elseif type(v) == 'table' then + findnums(v, out) + end + end + return out +end + +local mult = pm.postp( + pm.all(lex.digit, pm.star(pm.all(lex.space, lex.times, lex.space, lex.digit))), + function (d) + local acc = 1 + for _, v in ipairs(findnums(d)) do + acc = acc * v + end + return acc + end) + +local add = pm.postp( + pm.all(mult, pm.star(pm.all(lex.space, lex.plus, lex.space, mult))), + function (d) + local acc = 0 + for _, v in ipairs(findnums(d)) do + acc = acc + v + end + return acc + end) + +local expr = add + +local test +if arg[1] then + local f = io.open(arg[1], 'r') + test = f:read '*a' + f:close() +else + test = [[10 + 5 * 2 + 10]] +end + +local eind, out = pm.parse(test, lexer, expr) +print(eind, out) |
