1
- -- $Id: re.lua,v 1.39 2010/11/04 19:44:18 roberto Exp $
1
+ -- $Id: re.lua,v 1.44 2013/03/26 20:11:40 roberto Exp $
2
2
3
3
-- imported functions and modules
4
4
local tonumber , type , print , error = tonumber , type , print , error
@@ -10,7 +10,7 @@ local m = require"lpeg"
10
10
-- on 'mm'
11
11
local mm = m
12
12
13
- -- pattern's metatable
13
+ -- pattern's metatable
14
14
local mt = getmetatable (mm .P (0 ))
15
15
16
16
@@ -71,8 +71,8 @@ updatelocale()
71
71
local I = m .P (function (s ,i ) print (i , s :sub (1 , i - 1 )); return i end )
72
72
73
73
74
- local function getdef (id , Defs )
75
- local c = Defs and Defs [id ]
74
+ local function getdef (id , defs )
75
+ local c = defs and defs [id ]
76
76
if not c then error (" undefined name: " .. id ) end
77
77
return c
78
78
end
@@ -102,27 +102,27 @@ local function equalcap (s, i, c)
102
102
end
103
103
104
104
105
- local S = (m . S ( " \f\n\r\t\v " ) + " --" * (any - Predef .nl )^ 0 )^ 0
105
+ local S = (Predef . space + " --" * (any - Predef .nl )^ 0 )^ 0
106
106
107
- 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
108
108
109
109
local arrow = S * " <-"
110
110
111
- local exp_follow = m .P " /" + " )" + " }" + " :}" + " ~}" + (name * arrow ) + - 1
111
+ local seq_follow = m .P " /" + " )" + " }" + " :}" + " ~} " + " | }" + (name * arrow ) + - 1
112
112
113
113
name = m .C (name )
114
114
115
115
116
- -- identifiers only have meaning in a given environment
117
- local Identifier = name * m .Carg (1 )
116
+ -- a defined name only have meaning in a given environment
117
+ local Def = name * m .Carg (1 )
118
118
119
119
local num = m .C (m .R " 09" ^ 1 ) * S / tonumber
120
120
121
121
local String = " '" * m .C ((any - " '" )^ 0 ) * " '" +
122
122
' "' * m .C ((any - ' "' )^ 0 ) * ' "'
123
123
124
124
125
- local defined = " %" * Identifier / function (c ,Defs )
125
+ local defined = " %" * Def / function (c ,Defs )
126
126
local cat = Defs and Defs [c ] or Predef [c ]
127
127
if not cat then error (" name '" .. c .. " ' undefined" ) end
128
128
return cat
@@ -139,7 +139,7 @@ local Class =
139
139
function (c , p ) return c == " ^" and any - p or p end
140
140
* " ]"
141
141
142
- local function adddef (t , k , Defs , exp )
142
+ local function adddef (t , k , exp )
143
143
if t [k ] then
144
144
error (" '" .. k .. " ' already defined as a rule" )
145
145
else
@@ -148,15 +148,22 @@ local function adddef (t, k, Defs, exp)
148
148
return t
149
149
end
150
150
151
- local function firstdef (n , Defs , r ) return adddef ({n }, n , Defs , r ) end
151
+ local function firstdef (n , r ) return adddef ({n }, n , r ) end
152
152
153
153
154
+ local function NT (n , b )
155
+ if not b then
156
+ error (" rule '" .. n .. " ' used outside a grammar" )
157
+ else return mm .V (n )
158
+ end
159
+ end
160
+
154
161
155
162
local exp = m .P { " Exp" ,
156
163
Exp = S * ( m .V " Grammar"
157
164
+ m .Cf (m .V " Seq" * (" /" * S * m .V " Seq" )^ 0 , mt .__add ) );
158
165
Seq = m .Cf (m .Cc (m .P " " ) * m .V " Prefix" ^ 0 , mt .__mul )
159
- * (# exp_follow + patt_error );
166
+ * (# seq_follow + patt_error );
160
167
Prefix = " &" * S * m .V " Prefix" / mt .__len
161
168
+ " !" * S * m .V " Prefix" / mt .__unm
162
169
+ m .V " Suffix" ;
@@ -167,11 +174,11 @@ local exp = m.P{ "Exp",
167
174
+ " ^" * ( m .Cg (num * m .Cc (mult ))
168
175
+ m .Cg (m .C (m .S " +-" * m .R " 09" ^ 1 ) * m .Cc (mt .__pow ))
169
176
)
170
- + " ->" * S * ( m .Cg (String * m .Cc (mt .__div ))
177
+ + " ->" * S * ( m .Cg (( String + num ) * m .Cc (mt .__div ))
171
178
+ m .P " {}" * m .Cc (nil , m .Ct )
172
- + m .Cg (Identifier / getdef * m .Cc (mt .__div ))
179
+ + m .Cg (Def / getdef * m .Cc (mt .__div ))
173
180
)
174
- + " =>" * S * m .Cg (Identifier / getdef * m .Cc (m .Cmt ))
181
+ + " =>" * S * m .Cg (Def / getdef * m .Cc (m .Cmt ))
175
182
) * S
176
183
)^ 0 , function (a ,b ,f ) return f (a ,b ) end );
177
184
Primary = " (" * m .V " Exp" * " )"
@@ -183,16 +190,17 @@ local exp = m.P{ "Exp",
183
190
+ " =" * name / function (n ) return mm .Cmt (mm .Cb (n ), equalcap ) end
184
191
+ m .P " {}" / mm .Cp
185
192
+ " {~" * m .V " Exp" * " ~}" / mm .Cs
193
+ + " {|" * m .V " Exp" * " |}" / mm .Ct
186
194
+ " {" * m .V " Exp" * " }" / mm .C
187
195
+ m .P " ." * m .Cc (any )
188
- + name * - arrow / mm . V
189
- + " < " * name * " > " / mm . V ;
190
- Definition = Identifier * arrow * m . V " Exp " ;
191
- Grammar = m .Cf (m .V " Definition" / firstdef * m .Cg (m .V " Definition" )^ 0 , adddef ) /
192
- mm .P
196
+ + ( name * - arrow + " < " * name * " > " ) * m . Cb ( " G " ) / NT ;
197
+ Definition = name * arrow * m . V " Exp " ;
198
+ Grammar = m . Cg ( m . Cc ( true ), " G " ) *
199
+ m .Cf (m .V " Definition" / firstdef * m .Cg (m .V " Definition" )^ 0 ,
200
+ adddef ) / mm .P
193
201
}
194
202
195
- local pattern = S * exp / mm .P * (- any + patt_error )
203
+ local pattern = S * m . Cg ( m . Cc ( false ), " G " ) * exp / mm .P * (- any + patt_error )
196
204
197
205
198
206
local function compile (p , defs )
@@ -214,11 +222,14 @@ end
214
222
local function find (s , p , i )
215
223
local cp = fmem [p ]
216
224
if not cp then
217
- cp = compile (p )
218
- cp = mm .P { mm .Cp () * cp + 1 * mm .V (1 ) }
225
+ cp = compile (p ) / 0
226
+ cp = mm .P { mm .Cp () * cp * mm . Cp () + 1 * mm .V (1 ) }
219
227
fmem [p ] = cp
220
228
end
221
- return cp :match (s , i or 1 )
229
+ local i , e = cp :match (s , i or 1 )
230
+ if i then return i , e - 1
231
+ else return i
232
+ end
222
233
end
223
234
224
235
local function gsub (s , p , rep )
0 commit comments