|
|
- -- -- $Id: re.lua,v 1.44 2013/03/26 20:11:40 roberto Exp $
-
- -- -- imported functions and modules
- -- local tonumber, type, print, error = tonumber, type, print, error
- -- local setmetatable = setmetatable
- -- local m = require"lpeg"
-
- -- -- 'm' will be used to parse expressions, and 'mm' will be used to
- -- -- create expressions; that is, 're' runs on 'm', creating patterns
- -- -- on 'mm'
- -- local mm = m
-
- -- -- pattern's metatable
- -- local mt = getmetatable(mm.P(0))
-
-
-
- -- -- No more global accesses after this point
- -- local version = _VERSION
- -- if version == "Lua 5.2" then _ENV = nil end
-
-
- -- local any = m.P(1)
-
-
- -- -- Pre-defined names
- -- local Predef = { nl = m.P"\n" }
-
-
- -- local mem
- -- local fmem
- -- local gmem
-
-
- -- local function updatelocale ()
- -- mm.locale(Predef)
- -- Predef.a = Predef.alpha
- -- Predef.c = Predef.cntrl
- -- Predef.d = Predef.digit
- -- Predef.g = Predef.graph
- -- Predef.l = Predef.lower
- -- Predef.p = Predef.punct
- -- Predef.s = Predef.space
- -- Predef.u = Predef.upper
- -- Predef.w = Predef.alnum
- -- Predef.x = Predef.xdigit
- -- Predef.A = any - Predef.a
- -- Predef.C = any - Predef.c
- -- Predef.D = any - Predef.d
- -- Predef.G = any - Predef.g
- -- Predef.L = any - Predef.l
- -- Predef.P = any - Predef.p
- -- Predef.S = any - Predef.s
- -- Predef.U = any - Predef.u
- -- Predef.W = any - Predef.w
- -- Predef.X = any - Predef.x
- -- mem = {} -- restart memoization
- -- fmem = {}
- -- gmem = {}
- -- local mt = {__mode = "v"}
- -- setmetatable(mem, mt)
- -- setmetatable(fmem, mt)
- -- setmetatable(gmem, mt)
- -- end
-
-
- -- updatelocale()
-
-
-
- -- local I = m.P(function (s,i) print(i, s:sub(1, i-1)); return i end)
-
-
- -- local function getdef (id, defs)
- -- local c = defs and defs[id]
- -- if not c then LogError("undefined name: " .. id) end
- -- return c
- -- end
-
-
- -- local function patt_error (s, i)
- -- local msg = (#s < i + 20) and s:sub(i)
- -- or s:sub(i,i+20) .. "..."
- -- msg = ("pattern error near '%s'"):format(msg)
- -- LogError(msg, 2)
- -- end
-
- -- local function mult (p, n)
- -- local np = mm.P(true)
- -- while n >= 1 do
- -- if n%2 >= 1 then np = np * p end
- -- p = p * p
- -- n = n/2
- -- end
- -- return np
- -- end
-
- -- local function equalcap (s, i, c)
- -- if type(c) ~= "string" then return nil end
- -- local e = #c + i
- -- if s:sub(i, e - 1) == c then return e else return nil end
- -- end
-
-
- -- local S = (Predef.space + "--" * (any - Predef.nl)^0)^0
-
- -- local name = m.R("AZ", "az", "__") * m.R("AZ", "az", "__", "09")^0
-
- -- local arrow = S * "<-"
-
- -- local seq_follow = m.P"/" + ")" + "}" + ":}" + "~}" + "|}" + (name * arrow) + -1
-
- -- name = m.C(name)
-
-
- -- -- a defined name only have meaning in a given environment
- -- local Def = name * m.Carg(1)
-
- -- local num = m.C(m.R"09"^1) * S / tonumber
-
- -- local String = "'" * m.C((any - "'")^0) * "'" +
- -- '"' * m.C((any - '"')^0) * '"'
-
-
- -- local defined = "%" * Def / function (c,Defs)
- -- local cat = Defs and Defs[c] or Predef[c]
- -- if not cat then LogError ("name '" .. c .. "' undefined") end
- -- return cat
- -- end
-
- -- local Range = m.Cs(any * (m.P"-"/"") * (any - "]")) / mm.R
-
- -- local item = defined + Range + m.C(any)
-
- -- local Class =
- -- "["
- -- * (m.C(m.P"^"^-1)) -- optional complement symbol
- -- * m.Cf(item * (item - "]")^0, mt.__add) /
- -- function (c, p) return c == "^" and any - p or p end
- -- * "]"
-
- -- local function adddef (t, k, exp)
- -- if t[k] then
- -- LogError("'"..k.."' already defined as a rule")
- -- else
- -- t[k] = exp
- -- end
- -- return t
- -- end
-
- -- local function firstdef (n, r) return adddef({n}, n, r) end
-
-
- -- local function NT (n, b)
- -- if not b then
- -- LogError("rule '"..n.."' used outside a grammar")
- -- else return mm.V(n)
- -- end
- -- end
-
-
- -- local exp = m.P{ "Exp",
- -- Exp = S * ( m.V"Grammar"
- -- + m.Cf(m.V"Seq" * ("/" * S * m.V"Seq")^0, mt.__add) );
- -- Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix"^0 , mt.__mul)
- -- * (#seq_follow + patt_error);
- -- Prefix = "&" * S * m.V"Prefix" / mt.__len
- -- + "!" * S * m.V"Prefix" / mt.__unm
- -- + m.V"Suffix";
- -- Suffix = m.Cf(m.V"Primary" * S *
- -- ( ( m.P"+" * m.Cc(1, mt.__pow)
- -- + m.P"*" * m.Cc(0, mt.__pow)
- -- + m.P"?" * m.Cc(-1, mt.__pow)
- -- + "^" * ( m.Cg(num * m.Cc(mult))
- -- + m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow))
- -- )
- -- + "->" * S * ( m.Cg((String + num) * m.Cc(mt.__div))
- -- + m.P"{}" * m.Cc(nil, m.Ct)
- -- + m.Cg(Def / getdef * m.Cc(mt.__div))
- -- )
- -- + "=>" * S * m.Cg(Def / getdef * m.Cc(m.Cmt))
- -- ) * S
- -- )^0, function (a,b,f) return f(a,b) end );
- -- Primary = "(" * m.V"Exp" * ")"
- -- + String / mm.P
- -- + Class
- -- + defined
- -- + "{:" * (name * ":" + m.Cc(nil)) * m.V"Exp" * ":}" /
- -- function (n, p) return mm.Cg(p, n) end
- -- + "=" * name / function (n) return mm.Cmt(mm.Cb(n), equalcap) end
- -- + m.P"{}" / mm.Cp
- -- + "{~" * m.V"Exp" * "~}" / mm.Cs
- -- + "{|" * m.V"Exp" * "|}" / mm.Ct
- -- + "{" * m.V"Exp" * "}" / mm.C
- -- + m.P"." * m.Cc(any)
- -- + (name * -arrow + "<" * name * ">") * m.Cb("G") / NT;
- -- Definition = name * arrow * m.V"Exp";
- -- Grammar = m.Cg(m.Cc(true), "G") *
- -- m.Cf(m.V"Definition" / firstdef * m.Cg(m.V"Definition")^0,
- -- adddef) / mm.P
- -- }
-
- -- local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error)
-
-
- -- local function compile (p, defs)
- -- if mm.type(p) == "pattern" then return p end -- already compiled
- -- local cp = pattern:match(p, 1, defs)
- -- if not cp then LogError("incorrect pattern", 3) end
- -- return cp
- -- end
-
- -- local function match (s, p, i)
- -- local cp = mem[p]
- -- if not cp then
- -- cp = compile(p)
- -- mem[p] = cp
- -- end
- -- return cp:match(s, i or 1)
- -- end
-
- -- local function find (s, p, i)
- -- local cp = fmem[p]
- -- if not cp then
- -- cp = compile(p) / 0
- -- cp = mm.P{ mm.Cp() * cp * mm.Cp() + 1 * mm.V(1) }
- -- fmem[p] = cp
- -- end
- -- local i, e = cp:match(s, i or 1)
- -- if i then return i, e - 1
- -- else return i
- -- end
- -- end
-
- -- local function gsub (s, p, rep)
- -- local g = gmem[p] or {} -- ensure gmem[p] is not collected while here
- -- gmem[p] = g
- -- local cp = g[rep]
- -- if not cp then
- -- cp = compile(p)
- -- cp = mm.Cs((cp / rep + 1)^0)
- -- g[rep] = cp
- -- end
- -- return cp:match(s)
- -- end
-
-
- -- -- exported names
- -- local re = {
- -- compile = compile,
- -- match = match,
- -- find = find,
- -- gsub = gsub,
- -- updatelocale = updatelocale,
- -- }
-
- -- if version == "Lua 5.1" then
- -- --I need this to work with strict.lua, sorry for breaking compatibility.
- -- --_G.re = re
- -- end
-
- -- return re
|