331: def initialize(str)
332: @spec_string = str
333: h = '[A-Fa-f0-9]'
334:
335: @re_string, @handler =
336: case @spec_string
337:
338:
339: when /%\*?(\[\[:[a-z]+:\]\])/
340: [ "(#{$1}+)", :extract_plain ]
341:
342:
343: when /%\*?(\d+)(\[\[:[a-z]+:\]\])/
344: [ "(#{$2}{1,#{$1}})", :extract_plain ]
345:
346:
347: when /%\*?\[([^\]]*)\]/
348: yes = $1
349: if /^\^/.match(yes) then no = yes[1..-1] else no = '^' + yes end
350: [ "([#{yes}]+)(?=[#{no}]|\\z)", :extract_plain ]
351:
352:
353: when /%\*?(\d+)\[([^\]]*)\]/
354: yes = $2
355: w = $1
356: [ "([#{yes}]{1,#{w}})", :extract_plain ]
357:
358:
359: when /%\*?i/
360: [ "([-+]?(?:(?:0[0-7]+)|(?:0[Xx]#{h}+)|(?:[1-9]\\d*)))", :extract_integer ]
361:
362:
363: when /%\*?(\d+)i/
364: n = $1.to_i
365: s = "("
366: if n > 1 then s += "[1-9]\\d{1,#{n-1}}|" end
367: if n > 1 then s += "0[0-7]{1,#{n-1}}|" end
368: if n > 2 then s += "[-+]0[0-7]{1,#{n-2}}|" end
369: if n > 2 then s += "[-+][1-9]\\d{1,#{n-2}}|" end
370: if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
371: if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
372: s += "\\d"
373: s += ")"
374: [ s, :extract_integer ]
375:
376:
377: when /%\*?[du]/
378: [ '([-+]?\d+)', :extract_decimal ]
379:
380:
381: when /%\*?(\d+)[du]/
382: n = $1.to_i
383: s = "("
384: if n > 1 then s += "[-+]\\d{1,#{n-1}}|" end
385: s += "\\d{1,#{$1}})"
386: [ s, :extract_decimal ]
387:
388:
389: when /%\*?[Xx]/
390: [ "([-+]?(?:0[Xx])?#{h}+)", :extract_hex ]
391:
392:
393: when /%\*?(\d+)[Xx]/
394: n = $1.to_i
395: s = "("
396: if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end
397: if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end
398: if n > 1 then s += "[-+]#{h}{1,#{n-1}}|" end
399: s += "#{h}{1,#{n}}"
400: s += ")"
401: [ s, :extract_hex ]
402:
403:
404: when /%\*?o/
405: [ '([-+]?[0-7]+)', :extract_octal ]
406:
407:
408: when /%\*?(\d+)o/
409: [ "([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})", :extract_octal ]
410:
411:
412: when /%\*?f/
413: [ '([-+]?((\d+(?>(?=[^\d.]|$)))|(\d*(\.(\d*([eE][-+]?\d+)?)))))', :extract_float ]
414:
415:
416: when /%\*?(\d+)f/
417: [ "(\\S{1,#{$1}})", :extract_float ]
418:
419:
420: when /%\*?(\d+)s/
421: [ "(\\S{1,#{$1}})", :extract_plain ]
422:
423:
424: when /%\*?s/
425: [ '(\S+)', :extract_plain ]
426:
427:
428: when /\s%\*?c/
429: [ "\\s*(.)", :extract_plain ]
430:
431:
432: when /%\*?c/
433: [ "(.)", :extract_plain ]
434:
435:
436: when /%\*?(\d+)c/
437: [ "(.{1,#{$1}})", :extract_plain ]
438:
439:
440: when /%%/
441: [ '(\s*%)', :nil_proc ]
442:
443:
444: else
445: [ "(#{Regexp.escape(@spec_string)})", :nil_proc ]
446: end
447:
448: @re_string = '\A' + @re_string
449: end