aboutsummaryrefslogtreecommitdiff
path: root/re.lua
diff options
context:
space:
mode:
authorSergio Medeiros <sqmedeiros@gmail.com>2015-03-23 15:09:08 -0300
committerSergio Medeiros <sqmedeiros@gmail.com>2015-03-23 15:09:08 -0300
commitf124b2d4449a13ac21af9581a44b4455d89eaddb (patch)
treee0486555ac811c5f712927f110bb7bcda8569adf /re.lua
parent0e93d536ba2d312502737cce2ab0cc21393c4842 (diff)
downloadlpeglabel-f124b2d4449a13ac21af9581a44b4455d89eaddb.tar.gz
lpeglabel-f124b2d4449a13ac21af9581a44b4455d89eaddb.tar.bz2
lpeglabel-f124b2d4449a13ac21af9581a44b4455d89eaddb.zip
Renaming "re.lua" to "relabel.lua".
Adding examples, README and lpeglabel.html
Diffstat (limited to 're.lua')
-rw-r--r--re.lua282
1 files changed, 0 insertions, 282 deletions
diff --git a/re.lua b/re.lua
deleted file mode 100644
index ef1edae..0000000
--- a/re.lua
+++ /dev/null
@@ -1,282 +0,0 @@
1-- $Id: re.lua,v 1.44 2013/03/26 20:11:40 roberto Exp $
2
3-- imported functions and modules
4local tonumber, type, print, error = tonumber, type, print, error
5local setmetatable = setmetatable
6local unpack = table.unpack
7local m = require"lpeglabel"
8
9-- 'm' will be used to parse expressions, and 'mm' will be used to
10-- create expressions; that is, 're' runs on 'm', creating patterns
11-- on 'mm'
12local mm = m
13
14-- pattern's metatable
15local mt = getmetatable(mm.P(0))
16
17
18
19-- No more global accesses after this point
20local version = _VERSION
21if version == "Lua 5.2" then _ENV = nil end
22
23
24local any = m.P(1)
25
26
27-- Pre-defined names
28local Predef = { nl = m.P"\n" }
29local tlabels = {}
30
31
32local mem
33local fmem
34local gmem
35
36
37local function updatelocale ()
38 mm.locale(Predef)
39 Predef.a = Predef.alpha
40 Predef.c = Predef.cntrl
41 Predef.d = Predef.digit
42 Predef.g = Predef.graph
43 Predef.l = Predef.lower
44 Predef.p = Predef.punct
45 Predef.s = Predef.space
46 Predef.u = Predef.upper
47 Predef.w = Predef.alnum
48 Predef.x = Predef.xdigit
49 Predef.A = any - Predef.a
50 Predef.C = any - Predef.c
51 Predef.D = any - Predef.d
52 Predef.G = any - Predef.g
53 Predef.L = any - Predef.l
54 Predef.P = any - Predef.p
55 Predef.S = any - Predef.s
56 Predef.U = any - Predef.u
57 Predef.W = any - Predef.w
58 Predef.X = any - Predef.x
59 mem = {} -- restart memoization
60 fmem = {}
61 gmem = {}
62 local mt = {__mode = "v"}
63 setmetatable(mem, mt)
64 setmetatable(fmem, mt)
65 setmetatable(gmem, mt)
66end
67
68
69updatelocale()
70
71
72
73local I = m.P(function (s,i) print(i, s:sub(1, i-1)); return i end)
74
75
76local function getdef (id, defs)
77 local c = defs and defs[id]
78 if not c then error("undefined name: " .. id) end
79 return c
80end
81
82
83local function patt_error (s, i)
84 local msg = (#s < i + 20) and s:sub(i)
85 or s:sub(i,i+20) .. "..."
86 msg = ("pattern error near '%s'"):format(msg)
87 error(msg, 2)
88end
89
90local function mult (p, n)
91 local np = mm.P(true)
92 while n >= 1 do
93 if n%2 >= 1 then np = np * p end
94 p = p * p
95 n = n/2
96 end
97 return np
98end
99
100local function equalcap (s, i, c)
101 if type(c) ~= "string" then return nil end
102 local e = #c + i
103 if s:sub(i, e - 1) == c then return e else return nil end
104end
105
106
107local S = (Predef.space + "--" * (any - Predef.nl)^0)^0
108
109local name = m.R("AZ", "az", "__") * m.R("AZ", "az", "__", "09")^0
110
111local arrow = S * "<-"
112
113local seq_follow = m.P"/" + ")" + "}" + ":}" + "~}" + "|}" + (name * arrow) + -1
114
115name = m.C(name)
116
117
118-- a defined name only have meaning in a given environment
119local Def = name * m.Carg(1)
120
121local num = m.C(m.R"09"^1) * S / tonumber
122
123local String = "'" * m.C((any - "'")^0) * "'" +
124 '"' * m.C((any - '"')^0) * '"'
125
126
127local defined = "%" * Def / function (c,Defs)
128 local cat = Defs and Defs[c] or Predef[c]
129 if not cat then error ("name '" .. c .. "' undefined") end
130 return cat
131end
132
133local Range = m.Cs(any * (m.P"-"/"") * (any - "]")) / mm.R
134
135local item = defined + Range + m.C(any)
136
137local Class =
138 "["
139 * (m.C(m.P"^"^-1)) -- optional complement symbol
140 * m.Cf(item * (item - "]")^0, mt.__add) /
141 function (c, p) return c == "^" and any - p or p end
142 * "]"
143
144local function adddef (t, k, exp)
145 if t[k] then
146 error("'"..k.."' already defined as a rule")
147 else
148 t[k] = exp
149 end
150 return t
151end
152
153local function firstdef (n, r) return adddef({n}, n, r) end
154
155
156local function NT (n, b)
157 if not b then
158 error("rule '"..n.."' used outside a grammar")
159 else return mm.V(n)
160 end
161end
162
163local function labchoice (...)
164 local t = { ... }
165 local n = #t
166 local p = t[1]
167 local i = 2
168 while i + 1 <= n do
169 p = mm.Lc(p, t[i+1], unpack(t[i]))
170 i = i + 2
171 end
172
173 return p
174end
175
176
177local exp = m.P{ "Exp",
178 Exp = S * ( m.V"Grammar"
179 + (m.V"Seq") * ("/" * m.V"Labels" * S * m.V"Seq")^1 / labchoice
180 + m.Cf(m.V"Seq" * ("/" * S * m.V"Seq")^0, mt.__add) );
181 Labels = m.Ct(m.P"{" * S * m.V"Label" * (S * "," * S * m.V"Label")^0 * S * "}");
182 Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix"^0 , mt.__mul)
183 * (#seq_follow + patt_error);
184 Prefix = "&" * S * m.V"Prefix" / mt.__len
185 + "!" * S * m.V"Prefix" / mt.__unm
186 + m.V"Suffix";
187 Suffix = m.Cf(m.V"Primary" * S *
188 ( ( m.P"+" * m.Cc(1, mt.__pow)
189 + m.P"*" * m.Cc(0, mt.__pow)
190 + m.P"?" * m.Cc(-1, mt.__pow)
191 + "^" * ( m.Cg(num * m.Cc(mult))
192 + m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow))
193 )
194 + "->" * S * ( m.Cg((String + num) * m.Cc(mt.__div))
195 + m.P"{}" * m.Cc(nil, m.Ct)
196 + m.Cg(Def / getdef * m.Cc(mt.__div))
197 )
198 + "=>" * S * m.Cg(Def / getdef * m.Cc(m.Cmt))
199 ) * S
200 )^0, function (a,b,f) return f(a,b) end );
201 Primary = "(" * m.V"Exp" * ")"
202 + String / mm.P
203 + Class
204 + defined
205 + "%{" * S * m.V"Label" * (S * "," * S * m.V"Label")^0 * S * "}" / mm.T
206 + "{:" * (name * ":" + m.Cc(nil)) * m.V"Exp" * ":}" /
207 function (n, p) return mm.Cg(p, n) end
208 + "=" * name / function (n) return mm.Cmt(mm.Cb(n), equalcap) end
209 + m.P"{}" / mm.Cp
210 + "{~" * m.V"Exp" * "~}" / mm.Cs
211 + "{|" * m.V"Exp" * "|}" / mm.Ct
212 + "{" * m.V"Exp" * "}" / mm.C
213 + m.P"." * m.Cc(any)
214 + (name * -arrow + "<" * name * ">") * m.Cb("G") / NT;
215 Label = num + name / function (f) return tlabels[f] end;
216 Definition = name * arrow * m.V"Exp";
217 Grammar = m.Cg(m.Cc(true), "G") *
218 m.Cf(m.V"Definition" / firstdef * m.Cg(m.V"Definition")^0,
219 adddef) / mm.P
220}
221
222local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error)
223
224
225local function compile (p, defs)
226 if mm.type(p) == "pattern" then return p end -- already compiled
227 local cp = pattern:match(p, 1, defs)
228 if not cp then error("incorrect pattern", 3) end
229 return cp
230end
231
232local function match (s, p, i)
233 local cp = mem[p]
234 if not cp then
235 cp = compile(p)
236 mem[p] = cp
237 end
238 return cp:match(s, i or 1)
239end
240
241local function find (s, p, i)
242 local cp = fmem[p]
243 if not cp then
244 cp = compile(p) / 0
245 cp = mm.P{ mm.Cp() * cp * mm.Cp() + 1 * mm.V(1) }
246 fmem[p] = cp
247 end
248 local i, e = cp:match(s, i or 1)
249 if i then return i, e - 1
250 else return i
251 end
252end
253
254local function gsub (s, p, rep)
255 local g = gmem[p] or {} -- ensure gmem[p] is not collected while here
256 gmem[p] = g
257 local cp = g[rep]
258 if not cp then
259 cp = compile(p)
260 cp = mm.Cs((cp / rep + 1)^0)
261 g[rep] = cp
262 end
263 return cp:match(s)
264end
265
266local function setlabels (t)
267 tlabels = t
268end
269
270-- exported names
271local re = {
272 compile = compile,
273 match = match,
274 find = find,
275 gsub = gsub,
276 updatelocale = updatelocale,
277 setlabels = setlabels
278}
279
280if version == "Lua 5.1" then _G.re = re end
281
282return re