re.lua 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. --- @diagnostic disable: no-unknown
  2. --
  3. -- Copyright 2007-2023, Lua.org & PUC-Rio (see 'lpeg.html' for license)
  4. -- written by Roberto Ierusalimschy
  5. --
  6. --- vendored from lpeg-1.1.0
  7. --- documentation available at runtime/lua/vim/_meta/re.lua
  8. -- imported functions and modules
  9. local tonumber, type, error = tonumber, type, error
  10. local setmetatable = setmetatable
  11. local m = require"lpeg"
  12. -- 'm' will be used to parse expressions, and 'mm' will be used to
  13. -- create expressions; that is, 're' runs on 'm', creating patterns
  14. -- on 'mm'
  15. local mm = m
  16. -- patterns' metatable
  17. local mt = getmetatable(mm.P(0))
  18. local version = _VERSION
  19. -- No more global accesses after this point
  20. _ENV = nil -- does no harm in Lua 5.1
  21. local any = m.P(1)
  22. -- Pre-defined names
  23. local Predef = { nl = m.P"\n" }
  24. local mem
  25. local fmem
  26. local gmem
  27. local function updatelocale ()
  28. mm.locale(Predef)
  29. Predef.a = Predef.alpha
  30. Predef.c = Predef.cntrl
  31. Predef.d = Predef.digit
  32. Predef.g = Predef.graph
  33. Predef.l = Predef.lower
  34. Predef.p = Predef.punct
  35. Predef.s = Predef.space
  36. Predef.u = Predef.upper
  37. Predef.w = Predef.alnum
  38. Predef.x = Predef.xdigit
  39. Predef.A = any - Predef.a
  40. Predef.C = any - Predef.c
  41. Predef.D = any - Predef.d
  42. Predef.G = any - Predef.g
  43. Predef.L = any - Predef.l
  44. Predef.P = any - Predef.p
  45. Predef.S = any - Predef.s
  46. Predef.U = any - Predef.u
  47. Predef.W = any - Predef.w
  48. Predef.X = any - Predef.x
  49. mem = {} -- restart memoization
  50. fmem = {}
  51. gmem = {}
  52. local mt0 = {__mode = "v"}
  53. setmetatable(mem, mt0)
  54. setmetatable(fmem, mt0)
  55. setmetatable(gmem, mt0)
  56. end
  57. updatelocale()
  58. -- local I = m.P(function (s,i) print(i, s:sub(1, i-1)); return i end)
  59. local function patt_error (s, i)
  60. local msg = (#s < i + 20) and s:sub(i)
  61. or s:sub(i,i+20) .. "..."
  62. msg = ("pattern error near '%s'"):format(msg)
  63. error(msg, 2)
  64. end
  65. local function mult (p, n)
  66. local np = mm.P(true)
  67. while n >= 1 do
  68. if n%2 >= 1 then np = np * p end
  69. p = p * p
  70. n = n/2
  71. end
  72. return np
  73. end
  74. local function equalcap (s, i, c)
  75. if type(c) ~= "string" then return nil end
  76. local e = #c + i
  77. if s:sub(i, e - 1) == c then return e else return nil end
  78. end
  79. local S = (Predef.space + "--" * (any - Predef.nl)^0)^0
  80. local name = m.R("AZ", "az", "__") * m.R("AZ", "az", "__", "09")^0
  81. local arrow = S * "<-"
  82. local seq_follow = m.P"/" + ")" + "}" + ":}" + "~}" + "|}" + (name * arrow) + -1
  83. name = m.C(name)
  84. -- a defined name only have meaning in a given environment
  85. local Def = name * m.Carg(1)
  86. local function getdef (id, defs)
  87. local c = defs and defs[id]
  88. if not c then error("undefined name: " .. id) end
  89. return c
  90. end
  91. -- match a name and return a group of its corresponding definition
  92. -- and 'f' (to be folded in 'Suffix')
  93. local function defwithfunc (f)
  94. return m.Cg(Def / getdef * m.Cc(f))
  95. end
  96. local num = m.C(m.R"09"^1) * S / tonumber
  97. local String = "'" * m.C((any - "'")^0) * "'" +
  98. '"' * m.C((any - '"')^0) * '"'
  99. local defined = "%" * Def / function (c,Defs)
  100. local cat = Defs and Defs[c] or Predef[c]
  101. if not cat then error ("name '" .. c .. "' undefined") end
  102. return cat
  103. end
  104. local Range = m.Cs(any * (m.P"-"/"") * (any - "]")) / mm.R
  105. local item = (defined + Range + m.C(any)) / m.P
  106. local Class =
  107. "["
  108. * (m.C(m.P"^"^-1)) -- optional complement symbol
  109. * (item * ((item % mt.__add) - "]")^0) /
  110. function (c, p) return c == "^" and any - p or p end
  111. * "]"
  112. local function adddef (t, k, exp)
  113. if t[k] then
  114. error("'"..k.."' already defined as a rule")
  115. else
  116. t[k] = exp
  117. end
  118. return t
  119. end
  120. local function firstdef (n, r) return adddef({n}, n, r) end
  121. local function NT (n, b)
  122. if not b then
  123. error("rule '"..n.."' used outside a grammar")
  124. else return mm.V(n)
  125. end
  126. end
  127. local exp = m.P{ "Exp",
  128. Exp = S * ( m.V"Grammar"
  129. + m.V"Seq" * ("/" * S * m.V"Seq" % mt.__add)^0 );
  130. Seq = (m.Cc(m.P"") * (m.V"Prefix" % mt.__mul)^0)
  131. * (#seq_follow + patt_error);
  132. Prefix = "&" * S * m.V"Prefix" / mt.__len
  133. + "!" * S * m.V"Prefix" / mt.__unm
  134. + m.V"Suffix";
  135. Suffix = m.V"Primary" * S *
  136. ( ( m.P"+" * m.Cc(1, mt.__pow)
  137. + m.P"*" * m.Cc(0, mt.__pow)
  138. + m.P"?" * m.Cc(-1, mt.__pow)
  139. + "^" * ( m.Cg(num * m.Cc(mult))
  140. + m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow))
  141. )
  142. + "->" * S * ( m.Cg((String + num) * m.Cc(mt.__div))
  143. + m.P"{}" * m.Cc(nil, m.Ct)
  144. + defwithfunc(mt.__div)
  145. )
  146. + "=>" * S * defwithfunc(mm.Cmt)
  147. + ">>" * S * defwithfunc(mt.__mod)
  148. + "~>" * S * defwithfunc(mm.Cf)
  149. ) % function (a,b,f) return f(a,b) end * S
  150. )^0;
  151. Primary = "(" * m.V"Exp" * ")"
  152. + String / mm.P
  153. + Class
  154. + defined
  155. + "{:" * (name * ":" + m.Cc(nil)) * m.V"Exp" * ":}" /
  156. function (n, p) return mm.Cg(p, n) end
  157. + "=" * name / function (n) return mm.Cmt(mm.Cb(n), equalcap) end
  158. + m.P"{}" / mm.Cp
  159. + "{~" * m.V"Exp" * "~}" / mm.Cs
  160. + "{|" * m.V"Exp" * "|}" / mm.Ct
  161. + "{" * m.V"Exp" * "}" / mm.C
  162. + m.P"." * m.Cc(any)
  163. + (name * -arrow + "<" * name * ">") * m.Cb("G") / NT;
  164. Definition = name * arrow * m.V"Exp";
  165. Grammar = m.Cg(m.Cc(true), "G") *
  166. ((m.V"Definition" / firstdef) * (m.V"Definition" % adddef)^0) / mm.P
  167. }
  168. local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error)
  169. local function compile (p, defs)
  170. if mm.type(p) == "pattern" then return p end -- already compiled
  171. local cp = pattern:match(p, 1, defs)
  172. if not cp then error("incorrect pattern", 3) end
  173. return cp
  174. end
  175. local function match (s, p, i)
  176. local cp = mem[p]
  177. if not cp then
  178. cp = compile(p)
  179. mem[p] = cp
  180. end
  181. return cp:match(s, i or 1)
  182. end
  183. local function find (s, p, i)
  184. local cp = fmem[p]
  185. if not cp then
  186. cp = compile(p) / 0
  187. cp = mm.P{ mm.Cp() * cp * mm.Cp() + 1 * mm.V(1) }
  188. fmem[p] = cp
  189. end
  190. local e
  191. i, e = cp:match(s, i or 1)
  192. if i then return i, e - 1
  193. else return i
  194. end
  195. end
  196. local function gsub (s, p, rep)
  197. local g = gmem[p] or {} -- ensure gmem[p] is not collected while here
  198. gmem[p] = g
  199. local cp = g[rep]
  200. if not cp then
  201. cp = compile(p)
  202. cp = mm.Cs((cp / rep + 1)^0)
  203. g[rep] = cp
  204. end
  205. return cp:match(s)
  206. end
  207. -- exported names
  208. local re = {
  209. compile = compile,
  210. match = match,
  211. find = find,
  212. gsub = gsub,
  213. updatelocale = updatelocale,
  214. }
  215. if version == "Lua 5.1" then _G.re = re end
  216. return re