home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / iria107a.lzh / script / sre_parse.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2000-11-17  |  20.1 KB  |  735 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.0)
  3.  
  4. import string
  5. import sys
  6. from sre_constants import *
  7. SPECIAL_CHARS = '.\\[{()*+?^$|'
  8. REPEAT_CHARS = '*+?{'
  9. DIGITS = tuple('0123456789')
  10. OCTDIGITS = tuple('01234567')
  11. HEXDIGITS = tuple('0123456789abcdefABCDEF')
  12. WHITESPACE = tuple(' \t\n\r\x0b\x0c')
  13. ESCAPES = {
  14.     '\\a': (LITERAL, 7),
  15.     '\\b': (LITERAL, 8),
  16.     '\\f': (LITERAL, 12),
  17.     '\\n': (LITERAL, 10),
  18.     '\\r': (LITERAL, 13),
  19.     '\\t': (LITERAL, 9),
  20.     '\\v': (LITERAL, 11),
  21.     '\\\\': (LITERAL, ord('\\')) }
  22. CATEGORIES = {
  23.     '\\A': (AT, AT_BEGINNING),
  24.     '\\b': (AT, AT_BOUNDARY),
  25.     '\\B': (AT, AT_NON_BOUNDARY),
  26.     '\\d': (IN, [
  27.         (CATEGORY, CATEGORY_DIGIT)]),
  28.     '\\D': (IN, [
  29.         (CATEGORY, CATEGORY_NOT_DIGIT)]),
  30.     '\\s': (IN, [
  31.         (CATEGORY, CATEGORY_SPACE)]),
  32.     '\\S': (IN, [
  33.         (CATEGORY, CATEGORY_NOT_SPACE)]),
  34.     '\\w': (IN, [
  35.         (CATEGORY, CATEGORY_WORD)]),
  36.     '\\W': (IN, [
  37.         (CATEGORY, CATEGORY_NOT_WORD)]),
  38.     '\\Z': (AT, AT_END) }
  39. FLAGS = {
  40.     'i': SRE_FLAG_IGNORECASE,
  41.     'L': SRE_FLAG_LOCALE,
  42.     'm': SRE_FLAG_MULTILINE,
  43.     's': SRE_FLAG_DOTALL,
  44.     'x': SRE_FLAG_VERBOSE,
  45.     't': SRE_FLAG_TEMPLATE,
  46.     'u': SRE_FLAG_UNICODE }
  47.  
  48. class Pattern:
  49.     
  50.     def __init__(self):
  51.         self.flags = 0
  52.         self.groups = 1
  53.         self.groupdict = { }
  54.  
  55.     
  56.     def getgroup(self, name = None):
  57.         gid = self.groups
  58.         self.groups = gid + 1
  59.         if name:
  60.             self.groupdict[name] = gid
  61.         
  62.         return gid
  63.  
  64.  
  65.  
  66. class SubPattern:
  67.     
  68.     def __init__(self, pattern, data = None):
  69.         self.pattern = pattern
  70.         if not data:
  71.             data = []
  72.         
  73.         self.data = data
  74.         self.width = None
  75.  
  76.     
  77.     def dump(self, level = 0):
  78.         nl = 1
  79.         for op, av in self.data:
  80.             print level * '  ' + op,
  81.             nl = 0
  82.             if op == 'in':
  83.                 print 
  84.                 nl = 1
  85.                 for op, a in av:
  86.                     print (level + 1) * '  ' + op, a
  87.                 
  88.             elif op == 'branch':
  89.                 print 
  90.                 nl = 1
  91.                 i = 0
  92.                 for a in av[1]:
  93.                     if i > 0:
  94.                         print level * '  ' + 'or'
  95.                     
  96.                     a.dump(level + 1)
  97.                     nl = 1
  98.                     i = i + 1
  99.                 
  100.             elif type(av) in (type(()), type([])):
  101.                 for a in av:
  102.                     pass
  103.                 
  104.             else:
  105.                 print av,
  106.                 nl = 0
  107.             if not nl:
  108.                 print 
  109.             
  110.         
  111.  
  112.     
  113.     def __repr__(self):
  114.         return repr(self.data)
  115.  
  116.     
  117.     def __len__(self):
  118.         return len(self.data)
  119.  
  120.     
  121.     def __delitem__(self, index):
  122.         del self.data[index]
  123.  
  124.     
  125.     def __getitem__(self, index):
  126.         return self.data[index]
  127.  
  128.     
  129.     def __setitem__(self, index, code):
  130.         self.data[index] = code
  131.  
  132.     
  133.     def __getslice__(self, start, stop):
  134.         return SubPattern(self.pattern, self.data[start:stop])
  135.  
  136.     
  137.     def insert(self, index, code):
  138.         self.data.insert(index, code)
  139.  
  140.     
  141.     def append(self, code):
  142.         self.data.append(code)
  143.  
  144.     
  145.     def getwidth(self):
  146.         if self.width:
  147.             return self.width
  148.         
  149.         lo = hi = 0x0L
  150.         for op, av in self.data:
  151.             if op is BRANCH:
  152.                 i = sys.maxint
  153.                 j = 0
  154.                 for av in av[1]:
  155.                     (l, h) = av.getwidth()
  156.                     i = min(i, l)
  157.                     j = max(j, h)
  158.                 
  159.                 lo = lo + i
  160.                 hi = hi + j
  161.             elif op is CALL:
  162.                 (i, j) = av.getwidth()
  163.                 lo = lo + i
  164.                 hi = hi + j
  165.             elif op is SUBPATTERN:
  166.                 (i, j) = av[1].getwidth()
  167.                 lo = lo + i
  168.                 hi = hi + j
  169.             elif op in (MIN_REPEAT, MAX_REPEAT):
  170.                 (i, j) = av[2].getwidth()
  171.                 lo = lo + long(i) * av[0]
  172.                 hi = hi + long(j) * av[1]
  173.             elif op in (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY):
  174.                 lo = lo + 1
  175.                 hi = hi + 1
  176.             elif op == SUCCESS:
  177.                 break
  178.             
  179.         
  180.         self.width = (int(min(lo, sys.maxint)), int(min(hi, sys.maxint)))
  181.         return self.width
  182.  
  183.  
  184.  
  185. class Tokenizer:
  186.     
  187.     def __init__(self, string):
  188.         self.string = string
  189.         self.index = 0
  190.         self._Tokenizer__next()
  191.  
  192.     
  193.     def __next(self):
  194.         if self.index >= len(self.string):
  195.             self.next = None
  196.             return None
  197.         
  198.         char = self.string[self.index]
  199.         if char[0] == '\\':
  200.             
  201.             try:
  202.                 c = self.string[self.index + 1]
  203.             except IndexError:
  204.                 raise error, 'bogus escape'
  205.  
  206.             char = char + c
  207.         
  208.         self.index = self.index + len(char)
  209.         self.next = char
  210.  
  211.     
  212.     def match(self, char, skip = 1):
  213.         if char == self.next:
  214.             if skip:
  215.                 self._Tokenizer__next()
  216.             
  217.             return 1
  218.         
  219.         return 0
  220.  
  221.     
  222.     def get(self):
  223.         this = self.next
  224.         self._Tokenizer__next()
  225.         return this
  226.  
  227.     
  228.     def tell(self):
  229.         return (self.index, self.next)
  230.  
  231.     
  232.     def seek(self, index):
  233.         (self.index, self.next) = index
  234.  
  235.  
  236.  
  237. def isident(char):
  238.     if char <= char:
  239.         pass
  240.     elif not char <= 'z':
  241.         if char <= char:
  242.             pass
  243.         elif not char <= 'Z':
  244.             pass
  245.     return char == '_'
  246.  
  247.  
  248. def isdigit(char):
  249.     return None if char <= char else char <= '9'
  250.  
  251.  
  252. def isname(name):
  253.     if not isident(name[0]):
  254.         return 0
  255.     
  256.     for char in name:
  257.         pass
  258.     
  259.     return 1
  260.  
  261.  
  262. def _group(escape, groups):
  263.     
  264.     try:
  265.         gid = int(escape[1:])
  266.         if gid and gid < groups:
  267.             return gid
  268.     except ValueError:
  269.         pass
  270.  
  271.     return None
  272.  
  273.  
  274. def _class_escape(source, escape):
  275.     code = ESCAPES.get(escape)
  276.     if code:
  277.         return code
  278.     
  279.     code = CATEGORIES.get(escape)
  280.     if code:
  281.         return code
  282.     
  283.     
  284.     try:
  285.         if escape[1:2] == 'x':
  286.             while source.next in HEXDIGITS and len(escape) < 4:
  287.                 escape = escape + source.get()
  288.             escape = escape[2:]
  289.             if len(escape) != 2:
  290.                 raise error, 'bogus escape: %s' % repr('\\' + escape)
  291.             
  292.             return (LITERAL, int(escape, 16) & 255)
  293.         elif str(escape[1:2]) in OCTDIGITS:
  294.             while source.next in OCTDIGITS and len(escape) < 5:
  295.                 escape = escape + source.get()
  296.             escape = escape[1:]
  297.             return (LITERAL, int(escape, 8) & 255)
  298.         
  299.         if len(escape) == 2:
  300.             return (LITERAL, ord(escape[1]))
  301.     except ValueError:
  302.         pass
  303.  
  304.     raise error, 'bogus escape: %s' % repr(escape)
  305.  
  306.  
  307. def _escape(source, escape, state):
  308.     code = CATEGORIES.get(escape)
  309.     if code:
  310.         return code
  311.     
  312.     code = ESCAPES.get(escape)
  313.     if code:
  314.         return code
  315.     
  316.     
  317.     try:
  318.         if escape[1:2] == 'x':
  319.             while source.next in HEXDIGITS and len(escape) < 4:
  320.                 escape = escape + source.get()
  321.             if len(escape) != 4:
  322.                 raise ValueError
  323.             
  324.             return (LITERAL, int(escape[2:], 16) & 255)
  325.         elif escape[1:2] == '0':
  326.             while source.next in OCTDIGITS and len(escape) < 4:
  327.                 escape = escape + source.get()
  328.             return (LITERAL, int(escape[1:], 8) & 255)
  329.         elif escape[1:2] in DIGITS:
  330.             here = source.tell()
  331.             if source.next in DIGITS:
  332.                 escape = escape + source.get()
  333.                 if escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and source.next in OCTDIGITS:
  334.                     escape = escape + source.get()
  335.                     return (LITERAL, int(escape[1:], 8) & 255)
  336.                 
  337.             
  338.             group = _group(escape, state.groups)
  339.             if group:
  340.                 return (GROUPREF, group)
  341.             
  342.             raise ValueError
  343.         
  344.         if len(escape) == 2:
  345.             return (LITERAL, ord(escape[1]))
  346.     except ValueError:
  347.         pass
  348.  
  349.     raise error, 'bogus escape: %s' % repr(escape)
  350.  
  351.  
  352. def _parse_sub(source, state, nested = 1):
  353.     items = []
  354.     while 1:
  355.         items.append(_parse(source, state))
  356.         if source.match('|'):
  357.             continue
  358.         
  359.         if not nested:
  360.             break
  361.         
  362.         if not (source.next) or source.match(')', 0):
  363.             break
  364.         else:
  365.             raise error, 'pattern not properly closed'
  366.     if len(items) == 1:
  367.         return items[0]
  368.     
  369.     subpattern = SubPattern(state)
  370.     while 1:
  371.         prefix = None
  372.         for item in items:
  373.             if prefix is None:
  374.                 prefix = item[0]
  375.             elif item[0] != prefix:
  376.                 break
  377.             
  378.         else:
  379.             for item in items:
  380.                 del item[0]
  381.             
  382.         break
  383.     for item in items:
  384.         pass
  385.     else:
  386.         set = []
  387.         for item in items:
  388.             set.append(item[0])
  389.         
  390.         return subpattern
  391.     subpattern.append((BRANCH, (None, items)))
  392.     return subpattern
  393.  
  394.  
  395. def _parse(source, state):
  396.     subpattern = SubPattern(state)
  397.     while 1:
  398.         if source.next in ('|', ')'):
  399.             break
  400.         
  401.         this = source.get()
  402.         if this is None:
  403.             break
  404.         
  405.         if state.flags & SRE_FLAG_VERBOSE:
  406.             if this in WHITESPACE:
  407.                 continue
  408.             
  409.             if this == '#':
  410.                 while 1:
  411.                     this = source.get()
  412.                     if this in (None, '\n'):
  413.                         break
  414.                     
  415.                 continue
  416.             
  417.         
  418.         if this and this[0] not in SPECIAL_CHARS:
  419.             subpattern.append((LITERAL, ord(this)))
  420.         elif this == '[':
  421.             set = []
  422.             if source.match('^'):
  423.                 set.append((NEGATE, None))
  424.             
  425.             start = set[:]
  426.             while 1:
  427.                 this = source.get()
  428.                 if this == ']' and set != start:
  429.                     break
  430.                 elif this and this[0] == '\\':
  431.                     code1 = _class_escape(source, this)
  432.                 elif this:
  433.                     code1 = (LITERAL, ord(this))
  434.                 else:
  435.                     raise error, 'unexpected end of regular expression'
  436.                 if source.match('-'):
  437.                     this = source.get()
  438.                     if this == ']':
  439.                         if code1[0] is IN:
  440.                             code1 = code1[1][0]
  441.                         
  442.                         set.append(code1)
  443.                         set.append((LITERAL, ord('-')))
  444.                         break
  445.                     elif this[0] == '\\':
  446.                         code2 = _class_escape(source, this)
  447.                     else:
  448.                         code2 = (LITERAL, ord(this))
  449.                     if code1[0] != LITERAL or code2[0] != LITERAL:
  450.                         raise error, 'illegal range'
  451.                     
  452.                     lo = code1[1]
  453.                     hi = code2[1]
  454.                     if hi < lo:
  455.                         raise error, 'illegal range'
  456.                     
  457.                     set.append((RANGE, (lo, hi)))
  458.                 elif code1[0] is IN:
  459.                     code1 = code1[1][0]
  460.                 
  461.                 set.append(code1)
  462.             if len(set) == 1 and set[0][0] is LITERAL:
  463.                 subpattern.append(set[0])
  464.             elif len(set) == 2 and set[0][0] is NEGATE and set[1][0] is LITERAL:
  465.                 subpattern.append((NOT_LITERAL, set[1][1]))
  466.             else:
  467.                 subpattern.append((IN, set))
  468.         elif this and this[0] in REPEAT_CHARS:
  469.             if this == '?':
  470.                 (min, max) = (0, 1)
  471.             elif this == '*':
  472.                 (min, max) = (0, MAXREPEAT)
  473.             elif this == '+':
  474.                 (min, max) = (1, MAXREPEAT)
  475.             elif this == '{':
  476.                 here = source.tell()
  477.                 (min, max) = (0, MAXREPEAT)
  478.                 lo = hi = ''
  479.                 while source.next in DIGITS:
  480.                     lo = lo + source.get()
  481.                 if source.match(','):
  482.                     while source.next in DIGITS:
  483.                         hi = hi + source.get()
  484.                 else:
  485.                     hi = lo
  486.                 if not source.match('}'):
  487.                     subpattern.append((LITERAL, ord(this)))
  488.                     source.seek(here)
  489.                     continue
  490.                 
  491.                 if lo:
  492.                     min = int(lo)
  493.                 
  494.                 if hi:
  495.                     max = int(hi)
  496.                 
  497.             else:
  498.                 raise error, 'not supported'
  499.             if subpattern:
  500.                 item = subpattern[-1:]
  501.             else:
  502.                 raise error, 'nothing to repeat'
  503.             if source.match('?'):
  504.                 subpattern[-1] = (MIN_REPEAT, (min, max, item))
  505.             else:
  506.                 subpattern[-1] = (MAX_REPEAT, (min, max, item))
  507.         elif this == '.':
  508.             subpattern.append((ANY, None))
  509.         elif this == '(':
  510.             group = 1
  511.             name = None
  512.             if source.match('?'):
  513.                 group = 0
  514.                 if source.match('P'):
  515.                     if source.match('<'):
  516.                         name = ''
  517.                         while 1:
  518.                             char = source.get()
  519.                             if char is None:
  520.                                 raise error, 'unterminated name'
  521.                             
  522.                             if char == '>':
  523.                                 break
  524.                             
  525.                             name = name + char
  526.                         group = 1
  527.                         if not isname(name):
  528.                             raise error, 'illegal character in group name'
  529.                         
  530.                     elif source.match('='):
  531.                         name = ''
  532.                         while 1:
  533.                             char = source.get()
  534.                             if char is None:
  535.                                 raise error, 'unterminated name'
  536.                             
  537.                             if char == ')':
  538.                                 break
  539.                             
  540.                             name = name + char
  541.                         if not isname(name):
  542.                             raise error, 'illegal character in group name'
  543.                         
  544.                         gid = state.groupdict.get(name)
  545.                         if gid is None:
  546.                             raise error, 'unknown group name'
  547.                         
  548.                         subpattern.append((GROUPREF, gid))
  549.                         continue
  550.                     else:
  551.                         char = source.get()
  552.                         if char is None:
  553.                             raise error, 'unexpected end of pattern'
  554.                         
  555.                         raise error, 'unknown specifier: ?P%s' % char
  556.                 elif source.match(':'):
  557.                     group = 2
  558.                 elif source.match('#'):
  559.                     while 1:
  560.                         if source.next is None or source.next == ')':
  561.                             break
  562.                         
  563.                         source.get()
  564.                     if not source.match(')'):
  565.                         raise error, 'unbalanced parenthesis'
  566.                     
  567.                     continue
  568.                 elif source.next in ('=', '!', '<'):
  569.                     char = source.get()
  570.                     dir = 1
  571.                     if char == '<':
  572.                         if source.next not in ('=', '!'):
  573.                             raise error, 'syntax error'
  574.                         
  575.                         dir = -1
  576.                         char = source.get()
  577.                     
  578.                     p = _parse_sub(source, state)
  579.                     if not source.match(')'):
  580.                         raise error, 'unbalanced parenthesis'
  581.                     
  582.                     if char == '=':
  583.                         subpattern.append((ASSERT, (dir, p)))
  584.                     else:
  585.                         subpattern.append((ASSERT_NOT, (dir, p)))
  586.                     continue
  587.                 else:
  588.                     while FLAGS.has_key(source.next):
  589.                         state.flags = state.flags | FLAGS[source.get()]
  590.             
  591.             if group:
  592.                 if group == 2:
  593.                     group = None
  594.                 else:
  595.                     group = state.getgroup(name)
  596.                 p = _parse_sub(source, state)
  597.                 if not source.match(')'):
  598.                     raise error, 'unbalanced parenthesis'
  599.                 
  600.                 subpattern.append((SUBPATTERN, (group, p)))
  601.             else:
  602.                 while 1:
  603.                     char = source.get()
  604.                     if char is None or char == ')':
  605.                         break
  606.                     
  607.                     raise error, 'unknown extension'
  608.         elif this == '^':
  609.             subpattern.append((AT, AT_BEGINNING))
  610.         elif this == '$':
  611.             subpattern.append((AT, AT_END))
  612.         elif this and this[0] == '\\':
  613.             code = _escape(source, this, state)
  614.             subpattern.append(code)
  615.         else:
  616.             raise error, 'parser error'
  617.     return subpattern
  618.  
  619.  
  620. def parse(str, flags = 0, pattern = None):
  621.     source = Tokenizer(str)
  622.     if pattern is None:
  623.         pattern = Pattern()
  624.     
  625.     pattern.flags = flags
  626.     p = _parse_sub(source, pattern, 0)
  627.     tail = source.get()
  628.     if tail == ')':
  629.         raise error, 'unbalanced parenthesis'
  630.     elif tail:
  631.         raise error, 'bogus characters at end of regular expression'
  632.     
  633.     if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE:
  634.         return parse(str, p.pattern.flags)
  635.     
  636.     return p
  637.  
  638.  
  639. def parse_template(source, pattern):
  640.     s = Tokenizer(source)
  641.     p = []
  642.     a = p.append
  643.     while 1:
  644.         this = s.get()
  645.         if this is None:
  646.             break
  647.         
  648.         if this and this[0] == '\\':
  649.             if this == '\\g':
  650.                 name = ''
  651.                 if s.match('<'):
  652.                     while 1:
  653.                         char = s.get()
  654.                         if char is None:
  655.                             raise error, 'unterminated group name'
  656.                         
  657.                         if char == '>':
  658.                             break
  659.                         
  660.                         name = name + char
  661.                 
  662.                 if not name:
  663.                     raise error, 'bad group name'
  664.                 
  665.                 
  666.                 try:
  667.                     index = int(name)
  668.                 except ValueError:
  669.                     if not isname(name):
  670.                         raise error, 'illegal character in group name'
  671.                     
  672.                     
  673.                     try:
  674.                         index = pattern.groupindex[name]
  675.                     except KeyError:
  676.                         raise IndexError, 'unknown group name'
  677.  
  678.  
  679.                 a((MARK, index))
  680.             elif len(this) > 1 and this[1] in DIGITS:
  681.                 code = None
  682.                 while 1:
  683.                     group = _group(this, pattern.groups + 1)
  684.                     if group:
  685.                         if s.next not in DIGITS or not _group(this + s.next, pattern.groups + 1):
  686.                             code = (MARK, int(group))
  687.                             break
  688.                         
  689.                     elif s.next in OCTDIGITS:
  690.                         this = this + s.get()
  691.                     else:
  692.                         break
  693.                 if not code:
  694.                     this = this[1:]
  695.                     code = (LITERAL, int(this[-6:], 8) & 255)
  696.                 
  697.                 a(code)
  698.             else:
  699.                 
  700.                 try:
  701.                     a(ESCAPES[this])
  702.                 except KeyError:
  703.                     for c in this:
  704.                         a((LITERAL, ord(c)))
  705.                     
  706.                 except:
  707.                     0
  708.  
  709.         else:
  710.             a((LITERAL, ord(this)))
  711.     return p
  712.  
  713.  
  714. def expand_template(template, match):
  715.     p = []
  716.     a = p.append
  717.     sep = match.string[:0]
  718.     if type(sep) is type(''):
  719.         char = chr
  720.     else:
  721.         char = unichr
  722.     for c, s in template:
  723.         if c is LITERAL:
  724.             a(char(s))
  725.         elif c is MARK:
  726.             s = match.group(s)
  727.             if s is None:
  728.                 raise error, 'empty group'
  729.             
  730.             a(s)
  731.         
  732.     
  733.     return string.join(p, sep)
  734.  
  735.