source: nagslang/level_serializer.py@ 89:102043902451

Last change on this file since 89:102043902451 was 89:102043902451, checked in by Stefano Rivera <stefano@…>, 8 years ago

Simple (subset of) YAML parser

File size: 2.2 KB
Line 
1'''
2Serializer and dumper for a simple, YAMLish format (actually a YAML subset).
3The top level object is a dict.
4lists and dicts can contain lists, dicts, and strings.
5'''
6
7import re
8# TODO: Dump pyyaml
9import yaml
10
11
12def dump(data, file_object):
13 yaml.dump(data, file_object, default_flow_style=False)
14
15
16spaces_re = re.compile(r'^(\s*)(.*)')
17list_re = re.compile(r'^(-\s+)(.*)')
18dict_re = re.compile(r'^([^-:]+):\s?(.*)')
19
20
21def load(file_object):
22 # Stack of (indent level, container object)
23 stack = [(0, {})]
24 indent = lambda: stack[-1][0]
25 obj = lambda: stack[-1][1]
26
27 # When a dict's value is a nested block, remember the key
28 parent_key = None
29
30 for line in file_object:
31 spaces, line = spaces_re.match(line).groups()
32
33 while len(spaces) < indent():
34 stack.pop()
35
36 lm = list_re.match(line)
37 dm = dict_re.match(line)
38 if len(spaces) == indent():
39 if lm:
40 assert isinstance(obj(), list) or parent_key
41 if isinstance(obj(), dict) and parent_key:
42 # Starting a list in a dict
43 stack.append((indent(), []))
44 stack[-2][1][parent_key] = obj()
45 parent_key = None
46 elif dm and isinstance(obj(), list):
47 # Left an embedded list
48 stack.pop()
49
50 if len(spaces) > indent():
51 # Nested dict
52 assert dm
53 assert parent_key
54 stack.append((len(spaces), {}))
55 stack[-2][1][parent_key] = obj()
56 parent_key = None
57
58 while lm and lm.group(2).startswith('-'):
59 # Nested lists
60 prefix, line = lm.groups()
61 stack.append((indent() + len(prefix), []))
62 stack[-2][1].append(obj())
63 lm = list_re.match(line)
64
65 if lm:
66 prefix, line = lm.groups()
67 dm = dict_re.match(line)
68 if dm:
69 stack.append((indent() + len(prefix), {}))
70 stack[-2][1].append(obj())
71 else:
72 obj().append(line)
73
74 if dm:
75 key, value = dm.groups()
76 if value:
77 obj()[key] = value
78 else:
79 parent_key = key
80
81 return stack[0][1]
Note: See TracBrowser for help on using the repository browser.