• Subject: Re: Extend the arithmetic expressions parser from lpeg example
• Date: Tue, 28 Jun 2011 21:24:36 +0200

```2011/6/22 Christophe Jorssen <jorssen.leraincy@free.fr>:
> Hello all,
>
> I'm trying to add basic functions parsing to the parser proposed in
> the lpeg webpage [1].
>

Hello all,

This question got answered on the luatex-list by Taco Hoekwater. Here
is the corrected code.

Best regards.

require("lpeg")
-- Lexical Elements
local Space = lpeg.S(" \n\t")^0
local Number = lpeg.C(lpeg.P"-"^-1 * lpeg.R("09")^1) * Space
local FactorOp = lpeg.C(lpeg.S("+-")) * Space
local TermOp = lpeg.C(lpeg.S("*/")) * Space
local Open = "(" * Space
local Close = ")" * Space

local lower_letter = lpeg.R("az")
local upper_letter = lpeg.R("AZ")
local digit = lpeg.R("09")
local letter = lower_letter + upper_letter
local alphanum = letter + digit
local alphanum_ = alphanum + lpeg.S("_")
local alpha_ = letter + lpeg.S("_")
local func_pattern = alpha_ * alphanum_^0
local func = lpeg.C(func_pattern) * Space
local param_beg = lpeg.P("(") * Space
local param_end = lpeg.P(")") * Space
local comma = lpeg.P(",") * Space

-- Auxiliary function
function eval (v1, op, v2)
if (op == "+") then return v1 + v2
elseif (op == "-") then return v1 - v2
elseif (op == "*") then return v1 * v2
elseif (op == "/") then return v1 / v2
end
end

function_table = {
["abs"] = function (x) return math.abs(x) end,
}

function evalfunc(f,x)
return function_table[f](x)
end

-- Grammar
local V = lpeg.V
G = lpeg.P{ "Exp",
Exp = lpeg.Cf(V"Factor" * lpeg.Cg(FactorOp * V"Factor")^0, eval);
Factor = lpeg.Cf(V"Term" * lpeg.Cg(TermOp * V"Term")^0, eval);
func_E = lpeg.Cf(lpeg.Cg(func) * param_beg * lpeg.Cg(V"Exp") *
lpeg.Cg(comma * V"Exp")^0 * param_end,  evalfunc);
Term = Number / tonumber + Open * V"Exp" * Close + V"func_E";
}

-- small example
print(lpeg.match(G, "3 + 5*9 / (1+1) - abs(-12)"))

--
Christophe

```