summaryrefslogtreecommitdiff
path: root/numpy/f2py/lib/parser/pattern_tools.py
blob: 9cd4b5a1cb8b5160c0049babfe31f9d8ec567358 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

import re

class Pattern:
    """
    p1 | p2    -> <p1> | <p2>
    p1 + p2    -> <p1> <p2>
    p1 & p2    -> <p1><p2>
    ~p1        -> [ <p1> ]
    ~~p1       -> [ <p1> ]...
    ~~~p1      -> <p1> [ <p1> ]...
    ~~~~p1     -> <p1> [ <p1> ]...
    abs(p1)    -> whole string match of <p1>
    p1.named(name) -> match of <p1> has name
    p1.match(string) -> return string match with <p1>
    """
    _special_symbol_map = {'.': '[.]',
                           '*': '[*]',
                           '+': '[+]',
                           '|': '[|]',
                           '(': r'\(',
                           ')': r'\)',
                           }

    def __init__(self, label, pattern, optional=0):
        self.label = label
        self.pattern = pattern
        self.optional = optional
        return

    def match(self, string):
        if hasattr(self, '_compiled_match'):
            return self._compiled.match(string)
        self._compiled = compiled = re.compile(self.pattern)
        return compiled.match(string)

    def __abs__(self):
        return Pattern(self.label, r'\A' + self.pattern+ r'\Z')

    def __repr__(self):
        return '%s(%r, %r)' % (self.__class__.__name__, self.label, self.pattern)

    def __or__(self, other):
        label = '( %s OR %s )' % (self.label, other.label)
        pattern = '(%s|%s)' % (self.pattern, other.pattern)
        return Pattern(label, pattern)

    def __and__(self, other):
        if isinstance(other, Pattern):
            label = '%s%s' % (self.label, other.label)
            pattern = self.pattern + other.pattern
        else:
            assert isinstance(other,str),`other`
            label = '%s%s' % (self.label, other)
            pattern = self.pattern + other
        return Pattern(label, pattern)

    def __rand__(self, other):
        assert isinstance(other,str),`other`
        label = '%s%s' % (other, self.label)
        pattern = other + self.pattern
        return Pattern(label, pattern)

    def __invert__(self):
        if self.optional:
            if self.optional==1:
                return Pattern(self.label + '...', self.pattern[:-1] + '*', 2)
            if self.optional==2:
                return Pattern('%s %s' % (self.label[1:-4].strip(), self.label), self.pattern[:-1] + '+', 3)
            return self
        label = '[ %s ]' % (self.label)
        pattern = '(%s)?' % (self.pattern)
        return Pattern(label, pattern, 1)

    def __add__(self, other):
        if isinstance(other, Pattern):
            label = '%s %s' % (self.label, other.label)
            pattern = self.pattern + r'\s*' + other.pattern
        else:
            assert isinstance(other,str),`other`
            label = '%s %s' % (self.label, other)
            other = self._special_symbol_map.get(other, other)
            pattern = self.pattern + r'\s*' + other
        return Pattern(label, pattern)

    def __radd__(self, other):
        assert isinstance(other,str),`other`
        label = '%s %s' % (other, self.label)
        other = self._special_symbol_map.get(other, other)
        pattern = other + r'\s*' + self.pattern
        return Pattern(label, pattern)

    def named(self, name = None):
        if name is None:
            label = self.label
            assert label[0]+label[-1]=='<>' and ' ' not in label,`label`
        else:
            label = '<%s>' % (name)
        pattern = '(?P%s%s)' % (label.replace('-','_'), self.pattern)
        return Pattern(label, pattern)

name = Pattern('<name>', r'[a-z]\w*')
digit_string = Pattern('<digit-string>',r'\d+')
sign = Pattern('<sign>',r'[+-]')
exponent_letter = Pattern('<exponent-letter>',r'[ED]')

kind_param = digit_string | name
signed_digit_string = ~sign + digit_string
int_literal_constant = digit_string + ~('_' + kind_param)
signed_int_literal_constant = ~sign + int_literal_constant

exponent = signed_digit_string
significand = digit_string + '.' + ~digit_string | '.' + digit_string
real_literal_constant = significand + ~(exponent_letter + exponent) + ~ ('_' + kind_param) | \
                        digit_string + exponent_letter + exponent + ~ ('_' + kind_param)
signed_real_literal_constant = ~sign + real_literal_constant


print signed_real_literal_constant