[luatex] [A bit out of topic] Extend the arithmetic expressions parser from lpeg example

Christophe Jorssen jorssen.leraincy at free.fr
Tue Jun 28 10:29:22 CEST 2011


Hello all,

I posted the following question to the lua list a week ago but got no
answer. So I try here... For sure, it is a bit out of topic (well, it
is remotely connected with some work on a lua way to perform math in
pgf) but I know there must be some lpeg (context?) wizards here who
could probably help me on this matter. Thanks in advance. Best
regards.

-- Begin forwarded mail
Hello all,

I'm trying to add basic functions parsing to the parser proposed in
the lpeg webpage [1].

Here is the code I adapted.

---------------
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 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 = C(func_pattern) * Space
local param_beg = P("(") * Space
local param_end = 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(Cg(func) * param_beg * lpeg.Cg(V("Exp")) *
           lpeg.Cg(comma * V("Exp"))^0 * param_end,evalfunc),
 Term = Number / tonumber + Open * V"Exp" * Close + func_E;
}

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

But, it does not work. I got this error

bad argument #2 to '?' (pattern expected, got nil)

In addition, I'm afraid I don't really understand the Cg capture
function. What would be, for instance, the structure captured by Cg
inside Exp for the above example.

Thanks in advance.

Best regards.

[1] http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html (at the very end)

--
Christophe


More information about the luatex mailing list