1
- -- $Id: re.lua,v 1.1 2009-02-21 19:49:19 nick Exp $
1
+ -- $Id: re.lua,v 1.39 2010/11/04 19:44:18 roberto Exp $
2
2
3
- local m = require " lpeg"
4
- local _G = _G
3
+ -- imported functions and modules
5
4
local tonumber , type , print , error = tonumber , type , print , error
6
- local mt = getmetatable (m .P (0 ))
5
+ local setmetatable = setmetatable
6
+ local m = require " lpeg"
7
+
8
+ -- 'm' will be used to parse expressions, and 'mm' will be used to
9
+ -- create expressions; that is, 're' runs on 'm', creating patterns
10
+ -- on 'mm'
11
+ local mm = m
12
+
13
+ -- pattern's metatable
14
+ local mt = getmetatable (mm .P (0 ))
15
+
16
+
17
+
18
+ -- No more global accesses after this point
19
+ local version = _VERSION
20
+ if version == " Lua 5.2" then _ENV = nil end
7
21
8
- module " re"
9
22
10
23
local any = m .P (1 )
11
24
25
+
12
26
-- Pre-defined names
13
- Predef = { nl = m .P " \n " }
27
+ local Predef = { nl = m .P " \n " }
28
+
29
+
30
+ local mem
31
+ local fmem
32
+ local gmem
33
+
34
+
35
+ local function updatelocale ()
36
+ mm .locale (Predef )
37
+ Predef .a = Predef .alpha
38
+ Predef .c = Predef .cntrl
39
+ Predef .d = Predef .digit
40
+ Predef .g = Predef .graph
41
+ Predef .l = Predef .lower
42
+ Predef .p = Predef .punct
43
+ Predef .s = Predef .space
44
+ Predef .u = Predef .upper
45
+ Predef .w = Predef .alnum
46
+ Predef .x = Predef .xdigit
47
+ Predef .A = any - Predef .a
48
+ Predef .C = any - Predef .c
49
+ Predef .D = any - Predef .d
50
+ Predef .G = any - Predef .g
51
+ Predef .L = any - Predef .l
52
+ Predef .P = any - Predef .p
53
+ Predef .S = any - Predef .s
54
+ Predef .U = any - Predef .u
55
+ Predef .W = any - Predef .w
56
+ Predef .X = any - Predef .x
57
+ mem = {} -- restart memoization
58
+ fmem = {}
59
+ gmem = {}
60
+ local mt = {__mode = " v" }
61
+ setmetatable (mem , mt )
62
+ setmetatable (fmem , mt )
63
+ setmetatable (gmem , mt )
64
+ end
65
+
66
+
67
+ updatelocale ()
68
+
14
69
15
70
16
71
local I = m .P (function (s ,i ) print (i , s :sub (1 , i - 1 )); return i end )
@@ -31,7 +86,7 @@ local function patt_error (s, i)
31
86
end
32
87
33
88
local function mult (p , n )
34
- local np = m .P (true )
89
+ local np = mm .P (true )
35
90
while n >= 1 do
36
91
if n % 2 >= 1 then np = np * p end
37
92
p = p * p
@@ -47,11 +102,13 @@ local function equalcap (s, i, c)
47
102
end
48
103
49
104
50
- local S = (m .S (" \t\n " ) + " --" * (any - m . S " \n " )^ 0 )^ 0
105
+ local S = (m .S (" \f\n\r\t\v " ) + " --" * (any - Predef . nl )^ 0 )^ 0
51
106
52
- local name = m .R (" AZ" , " az" ) * m .R (" AZ" , " az" , " 09" )^ 0
107
+ local name = m .R (" AZ" , " az" ) * m .R (" AZ" , " az" , " __ " , " 09" )^ 0
53
108
54
- local exp_follow = m .P " /" + " )" + " }" + " :}" + " ~}" + name + - 1
109
+ local arrow = S * " <-"
110
+
111
+ local exp_follow = m .P " /" + " )" + " }" + " :}" + " ~}" + (name * arrow ) + - 1
55
112
56
113
name = m .C (name )
57
114
@@ -65,15 +122,15 @@ local String = "'" * m.C((any - "'")^0) * "'" +
65
122
' "' * m .C ((any - ' "' )^ 0 ) * ' "'
66
123
67
124
68
- local Cat = " %" * Identifier / function (c ,Defs )
125
+ local defined = " %" * Identifier / function (c ,Defs )
69
126
local cat = Defs and Defs [c ] or Predef [c ]
70
127
if not cat then error (" name '" .. c .. " ' undefined" ) end
71
128
return cat
72
129
end
73
130
74
- local Range = m .Cs (any * (m .P " -" / " " ) * (any - " ]" )) / m .R
131
+ local Range = m .Cs (any * (m .P " -" / " " ) * (any - " ]" )) / mm .R
75
132
76
- local item = Cat + Range + m .C (any )
133
+ local item = defined + Range + m .C (any )
77
134
78
135
local Class =
79
136
" ["
@@ -118,39 +175,34 @@ local exp = m.P{ "Exp",
118
175
) * S
119
176
)^ 0 , function (a ,b ,f ) return f (a ,b ) end );
120
177
Primary = " (" * m .V " Exp" * " )"
121
- + String / m .P
178
+ + String / mm .P
122
179
+ Class
123
- + Cat
180
+ + defined
124
181
+ " {:" * (name * " :" + m .Cc (nil )) * m .V " Exp" * " :}" /
125
- function (n , p ) return m .Cg (p , n ) end
126
- + " =" * name / function (n ) return m .Cmt (m .Cb (n ), equalcap ) end
127
- + m .P " {}" / m .Cp
128
- + " {~" * m .V " Exp" * " ~}" / m .Cs
129
- + " {" * m .V " Exp" * " }" / m .C
182
+ function (n , p ) return mm .Cg (p , n ) end
183
+ + " =" * name / function (n ) return mm .Cmt (mm .Cb (n ), equalcap ) end
184
+ + m .P " {}" / mm .Cp
185
+ + " {~" * m .V " Exp" * " ~}" / mm .Cs
186
+ + " {" * m .V " Exp" * " }" / mm .C
130
187
+ m .P " ." * m .Cc (any )
131
- + " <" * name * " >" / m .V ;
132
- Definition = Identifier * S * ' <-' * m .V " Exp" ;
188
+ + name * - arrow / mm .V
189
+ + " <" * name * " >" / mm .V ;
190
+ Definition = Identifier * arrow * m .V " Exp" ;
133
191
Grammar = m .Cf (m .V " Definition" / firstdef * m .Cg (m .V " Definition" )^ 0 , adddef ) /
134
- m .P
192
+ mm .P
135
193
}
136
194
137
- local pattern = S * exp / m .P * (- any + patt_error )
195
+ local pattern = S * exp / mm .P * (- any + patt_error )
138
196
139
197
140
- function compile (p , defs )
141
- if m .type (p ) == " pattern" then return p end -- already compiled
198
+ local function compile (p , defs )
199
+ if mm .type (p ) == " pattern" then return p end -- already compiled
142
200
local cp = pattern :match (p , 1 , defs )
143
201
if not cp then error (" incorrect pattern" , 3 ) end
144
202
return cp
145
203
end
146
204
147
-
148
- local mem
149
- local fmem
150
- local gmem
151
- local mt = {__mode = " v" }
152
-
153
- function match (s , p , i )
205
+ local function match (s , p , i )
154
206
local cp = mem [p ]
155
207
if not cp then
156
208
cp = compile (p )
@@ -159,58 +211,38 @@ function match (s, p, i)
159
211
return cp :match (s , i or 1 )
160
212
end
161
213
162
- function find (s , p , i )
214
+ local function find (s , p , i )
163
215
local cp = fmem [p ]
164
216
if not cp then
165
217
cp = compile (p )
166
- cp = m .P { m .Cp () * cp + 1 * m .V (1 ) }
218
+ cp = mm .P { mm .Cp () * cp + 1 * mm .V (1 ) }
167
219
fmem [p ] = cp
168
220
end
169
221
return cp :match (s , i or 1 )
170
222
end
171
223
172
- function gsub (s , p , rep )
173
- gmem [p ] = gmem [p ] or {}
174
- local cp = gmem [p ][rep ]
224
+ local function gsub (s , p , rep )
225
+ local g = gmem [p ] or {} -- ensure gmem[p] is not collected while here
226
+ gmem [p ] = g
227
+ local cp = g [rep ]
175
228
if not cp then
176
229
cp = compile (p )
177
- cp = m .Cs ((cp / rep + 1 )^ 0 )
178
- gmem [ p ] [rep ] = cp
230
+ cp = mm .Cs ((cp / rep + 1 )^ 0 )
231
+ g [rep ] = cp
179
232
end
180
233
return cp :match (s )
181
234
end
182
235
183
236
184
- function updatelocale ()
185
- m .locale (Predef )
186
- Predef .a = Predef .alpha
187
- Predef .c = Predef .cntrl
188
- Predef .d = Predef .digit
189
- Predef .g = Predef .graph
190
- Predef .l = Predef .lower
191
- Predef .p = Predef .punct
192
- Predef .s = Predef .space
193
- Predef .u = Predef .upper
194
- Predef .w = Predef .alnum
195
- Predef .x = Predef .xdigit
196
- Predef .A = any - Predef .a
197
- Predef .C = any - Predef .c
198
- Predef .D = any - Predef .d
199
- Predef .G = any - Predef .g
200
- Predef .L = any - Predef .l
201
- Predef .P = any - Predef .p
202
- Predef .S = any - Predef .s
203
- Predef .U = any - Predef .u
204
- Predef .W = any - Predef .w
205
- Predef .X = any - Predef .x
206
- mem = {} -- restart memoization
207
- fmem = {}
208
- gmem = {}
209
- _G .setmetatable (mem , mt )
210
- _G .setmetatable (fmem , mt )
211
- _G .setmetatable (gmem , mt )
212
- end
213
-
237
+ -- exported names
238
+ local re = {
239
+ compile = compile ,
240
+ match = match ,
241
+ find = find ,
242
+ gsub = gsub ,
243
+ updatelocale = updatelocale ,
244
+ }
214
245
215
- updatelocale ()
246
+ if version == " Lua 5.1 " then _G . re = re end
216
247
248
+ return re
0 commit comments