overnord / aml

Simple parser for the AML Markup Language.

Clone this repository (size: 162.6 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/overnord/aml/
commit 68: 2e4d340fca6a
parent 67: 323ba3fe906b
branch: default
added indexing for aml.path
Björn Schulz / overnord
8 months ago

Changed (Δ1014 bytes):

raw changeset »

aml/path/parser.py (24 lines added, 13 lines removed)

aml/path/path.py (5 lines added, 33 lines removed)

aml/path/scanner.py (3 lines added, 3 lines removed)

Up to file-list aml/path/parser.py:

@@ -23,22 +23,31 @@ class Parser(object):
23
23
        v = self.v
24
24
        self.advance()
25
25
        return v
26
    
27
    def parse_attributes(self):
26
27
    def parse_parentheses(self):
28
28
        attributes = {}
29
        index = None
29
30
        if self.t == '[':
30
31
            self.advance()
31
            while self.t != ']':
32
                key = self.expect('name')
33
                self.expect('=')
34
                attributes[key] = self.expect('value')
35
                if self.t != ']':
36
                    self.expect(';')
37
            self.expect(']')
38
        return attributes
32
            if self.t == 'value':
33
                index = self.expect('value')
34
                self.expect(']')
35
            else:
36
                while self.t != ']':
37
                    name = self.expect('name')
38
                    self.expect('=')
39
                    attributes[name] = self.expect('value')
40
                    if self.t != ']':
41
                        self.expect(';')
42
                self.expect(']')
43
                if self.t == '[':
44
                    self.advance()
45
                    index = self.expect('value')
46
                    self.expect(']')
47
        return attributes, index
39
48
    
40
49
    def parse_path(self, name):
41
        path = Path(name, self.parse_attributes())
50
        path = Path(name, *self.parse_parentheses())
42
51
        if self.t == '/':
43
52
            self.advance()
44
53
            if self.t:
@@ -53,9 +62,11 @@ class Parser(object):
53
62
            if t == '/':
54
63
                if self.t == '/':
55
64
                    self.advance()
56
                    path = Any(self.expect('name'), self.parse_attributes())
65
                    path = Any(self.expect('name'))
57
66
                else:
58
                    path = Root(self.expect('name'), self.parse_attributes())
67
                    path = Root(self.expect('name'))
68
                attributes, index = self.parse_parentheses()
69
                path.attributes = attributes
59
70
            elif v == '.':
60
71
                path = Self()
61
72
            elif v == '..':

Up to file-list aml/path/path.py:

8
8
9
9
class Path(object):
10
10
    
11
    def __init__(self, name, attributes=None, child=None):
11
    def __init__(self, name, attributes=None, index=None, child=None):
12
12
        self.name = name
13
13
        self.attributes = attributes or {}
14
        self.index = index
14
15
        self.child = child
15
16
    
16
17
    def __repr__(self):
@@ -21,17 +22,12 @@ class Path(object):
21
22
            self.child
22
23
        )
23
24
    
24
    def __str__(self):
25
        return '%s[%s]/%s' % (
26
            self.name,
27
            ';'.join('%s=%r' % i for i in self.attributes.items()),
28
            self.child or ''
29
        )
30
    
31
25
    def match(self, node):
32
26
        return (
33
27
            (node.name == self.name or self.name == '*') and
34
            all(node[k] == self.attributes[k] for k in self.attributes)
28
            all(node[k] == self.attributes[k] for k in self.attributes) and
29
            node.parent.children.index(node) == self.index
30
            if self.index is not None else True
35
31
        )
36
32
    
37
33
    def findall(self, node):
@@ -45,13 +41,6 @@ class Path(object):
45
41
46
42
class Root(Path):
47
43
    
48
    def __str__(self):
49
        return '/%s[%s]/%s' % (
50
            self.name,
51
            ';'.join('%s=%r' % i for i in self.attributes.items()),
52
            self.child or ''
53
        )
54
    
55
44
    def root(self, node):
56
45
        while node.parent is not None:
57
46
            node = node.parent
@@ -69,13 +58,6 @@ class Root(Path):
69
58
70
59
class Any(Path):
71
60
    
72
    def __str__(self):
73
        return '//%s[%s]/%s' % (
74
            self.name,
75
            ';'.join('%s=%r' % i for i in self.attributes.items()),
76
            self.child or ''
77
        )
78
    
79
61
    def flatten(self, node):
80
62
        yield node
81
63
        for n in node:
@@ -101,11 +83,6 @@ class Self(object):
101
83
            self.child
102
84
        )
103
85
    
104
    def __str__(self):
105
        return './%s' % (
106
            self.child or ''
107
        )
108
    
109
86
    def findall(self, node):
110
87
        if self.child is None:
111
88
            yield node
@@ -124,11 +101,6 @@ class Parent(object):
124
101
            self.child
125
102
        )
126
103
    
127
    def __str__(self):
128
        return '../%s' % (
129
            self.child or ''
130
        )
131
    
132
104
    def findall(self, node):
133
105
        if self.child is None:
134
106
            if node.parent is None:

Up to file-list aml/path/scanner.py:

1
1
'''
2
    aml.scanner
3
    ~~~~~~~~~~~
2
    aml.path.scanner
3
    ~~~~~~~~~~~~~~~~
4
4
5
5
    :copyright: 2009 by Bjoern Schulz <bjoern.schulz.92@gmail.com>
6
6
    :license: MIT, see LICENSE for more details
@@ -11,7 +11,7 @@ import re
11
11
def Scanner(src):
12
12
    for m in re.finditer((r'([-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?)'
13
13
                          r'|(\w+)|#(t|f|n)|"([^"\\]*(?:\\.[^"\\]*)*)"'
14
                          r"|'([^'\\]*(?:\\.[^'\\]*)*)'|([()])|;.*?\n|\s+"),
14
                          r"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\/\[\]=;])|\s+"),
15
15
                         src, re.UNICODE):
16
16
        if m.lastindex:
17
17
            t = m.group(m.lastindex)