Transformar (cond? Entonces: else) a ifthenelse (cond, entonces, else) con LPEG
Pregunta
Estoy tratando de convertir una cadena como 'a?(b?c:d):e'
a otra cadena 'ifthenelse(a,ifthenelse(b,c,d),e)'
utilizando el LPEG Lua Parser. Lentamente estoy aprendiendo a usar LPEG, pero aún así no puedo encontrar una solución adecuada para hacer esto con capturas. ¿Algunas ideas?
Esto es lo que hice hasta ahora.
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"))
Solución 2
Aquí hay otra solución al problema dado por William Ahern en la lista de Lua.
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"))
Otros consejos
Cambié un poco la gramática, pero sigue siendo lo mismo: creo:
S = E "?" E ":" E | E
E = "(" S ")" | T
T = (L | D) +
L = [a-z] | [A-Z]
D = [0-9]
La gramática sin capturas:
local grammar = lpeg.P{
"S";
S = (lpeg.V"E" * lpeg.P"?" * lpeg.V"E" * lpeg.P":" * lpeg.V"E") + lpeg.V"E",
E = (lpeg.P"(" * lpeg.V"S" * lpeg.P")") + lpeg.V"T",
T = (lpeg.V"L" + lpeg.V"D")^1,
L = lpeg.R("az") + lpeg.R("AZ"),
D = lpeg.R("09")
}
La gramática con capturas:
local grammar2 = lpeg.P{
"S";
S = (lpeg.Cs(lpeg.V"E") / "ifthenelse(%1") * (lpeg.P"?" / ",") * lpeg.V"E" * (lpeg.P":" / ",") * (lpeg.Cs(lpeg.V"E") / "%1)") + lpeg.V"E",
E = (lpeg.P"(" / "") * lpeg.V"S" * (lpeg.P")" / "") + lpeg.V"T",
T = (lpeg.V"L" + lpeg.V"D")^1,
L = lpeg.R("az") + lpeg.R("AZ"),
D = lpeg.R("09")
}
Capturas reemplazar:
- "(" y ")" con cadena vacía (
lpeg.P"(" / ""
ylpeg.P")" / "")
) - Primera coincidencia variable con "ifthenelse (variable" (
lpeg.Cs(lpeg.V"E") / "ifthenelse(%1")
) - "?" y con "," (
lpeg.P"?" / ","
ylpeg.P":" / ","
) - Última variable coincidencia con "variable)" (
lpeg.Cs(lpeg.V"E") / "%1)"
)
Algunas pruebas aleatorias (salida en comentarios):
print( lpeg.match( lpeg.Cs(grammar2), "a") )
-- a
print( lpeg.match( lpeg.Cs(grammar2), "a?b:c") )
-- ifthenelse(a,b,c)
print( lpeg.match( lpeg.Cs(grammar2), "a?(i?j:k):c") )
-- ifthenelse(a,ifthenelse(i,j,k),c)
print( lpeg.match( lpeg.Cs(grammar2), "(a?(i?j:(x?y:z)):b)?c:(u?v:w)") )
-- ifthenelse(ifthenelse(a,ifthenelse(i,j,ifthenelse(x,y,z)),b),c,ifthenelse(u,v,w))
Espero que puedas continuar desde aquí.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow