@@ -216,9 +216,14 @@ class item(Parameterized):
216
216
((u'foo', u'baz@mumble.net'), 20)
217
217
"""
218
218
219
+ QUOTES = True
220
+
219
221
def __init__ (self , default = 'token_or_quoted_string' , rules = {}):
220
222
self .default = default and production (default )
221
- self .grammar = dict ((k , production (v )) for (k , v ) in rules .iteritems ())
223
+ self .grammar = dict (
224
+ (k , maybe_unquote (production (v )))
225
+ for (k , v ) in rules .iteritems ()
226
+ )
222
227
223
228
def production (self , name ):
224
229
"""Find the production for a value based on an item's name.
@@ -246,6 +251,7 @@ def write(self, data):
246
251
))
247
252
248
253
class quote (Parameterized ):
254
+ QUOTES = True
249
255
250
256
def __init__ (self , kind = None ):
251
257
self .kind = production (kind ) if kind else element_list (token , min = 1 )
@@ -263,6 +269,39 @@ def write(self, data):
263
269
dq = double_quote .write (None )
264
270
return u'%s%s%s' % (dq , self .kind .write (data ), dq )
265
271
272
+ class MaybeUnquote (Parameterized ):
273
+ def __init__ (self , kind ):
274
+ self .kind = kind
275
+ self .write = kind .write
276
+
277
+ def read (self , data , pos = 0 ):
278
+ if data [pos ] != '"' :
279
+ return self .kind .read (data , pos )
280
+ try :
281
+ (quoted , new_pos ) = require (quoted_string , data , pos )
282
+ (value , val_pos ) = require (self .kind , quoted , 0 )
283
+ if val_pos == len (quoted ):
284
+ return (value , new_pos )
285
+ return (None , pos )
286
+ except BadToken :
287
+ return (None , pos )
288
+
289
+ def write (self , data ):
290
+ return self .kind .write (data )
291
+
292
+ def maybe_unquote (prod ):
293
+ """
294
+ >>> int = maybe_unquote(integer)
295
+ >>> int.read('123')
296
+ (123, 3)
297
+ >>> int.read("123")
298
+ (123, 3)
299
+ >>> int.read("foo")
300
+ (None, 0)
301
+ """
302
+ prod = production (prod )
303
+ return prod if getattr (prod , 'QUOTES' , False ) else MaybeUnquote (prod )
304
+
266
305
267
306
### Simple Productions
268
307
@@ -279,6 +318,7 @@ class token_or_quoted_string(Production):
279
318
u'"frob@mumble.net"'
280
319
"""
281
320
321
+ QUOTES = True
282
322
SEPARATOR = re .compile (r'[\(\)<>@,;:\\"/\[\]\?={}\s]' )
283
323
284
324
@classmethod
@@ -305,6 +345,7 @@ class quoted_string(Production):
305
345
(None, 0)
306
346
"""
307
347
348
+ QUOTES = True
308
349
UNESCAPE = re .compile (r'\\(.)' )
309
350
310
351
@regular (r'"((?:\\.|[^"])+)"' )
0 commit comments