Search code examples
lualpeg

Transform (cond ? then : else) to ifthenelse(cond,then,else) with lpeg


I'm trying to convert a string like 'a?(b?c:d):e' to another string 'ifthenelse(a,ifthenelse(b,c,d),e)' using the lpeg lua parser. I'm slowly learning how to use lpeg but still I can't find a suitable solution to do this with captures. Any ideas?

Here is what I did so far.

local lpeg = require("lpeg")

local S, P, R = lpeg.S, lpeg.P, lpeg.R
local C, Cc, Ct = lpeg.C, lpeg.Cc, lpeg.Ct
local Cf, Cg, Cs = lpeg.Cf, lpeg.Cg, lpeg.Cs
local V = lpeg.V

local thenop = P("?")
local elseop = P(":")
local openpar = P("(")
local closepar = P(")")
local digit = R("09")
local letter = R("az") + R("AZ")

local parser = 
   P({
    "F",
    F = V("E") * (thenop * V("E") * elseop * V("E"))^0,
    E = (letter + digit)^1 + (openpar * V("F") * closepar)
 }) -- * -1 -- Is it needed?
print(lpeg.match(parser,"a?(b?c:d):e"))
print(lpeg.match(parser,"a"))

Solution

  • Here is another solution to the problem given by William Ahern on the lua-list.

    local lpeg = require("lpeg")
    
    lpeg.locale(lpeg)
    
    local function tr(a, b, c)
       if not b then
           return a
       else
           return string.format("ifthenelse(%s,%s,%s)", a, b, c)
       end
    end
    
    local var = lpeg.C(lpeg.alpha * (lpeg.alnum^0))
    
    local E, G = lpeg.V"E", lpeg.V"G"
    
    local grammar = lpeg.P{ "E",
       E = ((var + G) * (lpeg.P"?" * E * lpeg.P":" * E)^-1) / tr,
       G = lpeg.P"(" * E * lpeg.P")",
    }
    
    print(lpeg.match(grammar, "a?(b?c:d):e"))