-
Notifications
You must be signed in to change notification settings - Fork 1
/
grammar.py
77 lines (63 loc) · 2.33 KB
/
grammar.py
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
import sys, random
def die(message):
print >> sys.stderr, "Error:", message
exit(1)
class Grammar(object):
_lines = []
nodes = {}
def add_node_option(self, node, fragment):
if not node in self.nodes:
self.nodes[node] = []
self.nodes[node].append(fragment)
def generate(self):
if not "__root__" in self.nodes:
die("no tweets are defined")
exit()
return self.expand_node("__root__")
def expand_node(self, node):
capitalise = node[0].isupper()
node = node.lower()
option = random.choice(self.nodes[node])
result = self.expand_option(option)
if capitalise:
result = result[0].upper() + result[1:]
return result
def expand_option(self, option):
result = option;
while result.find("{") != -1:
start = result.find("{")
end = result.find("}", start+1)
if end == -1:
die("on line %s the '{' at column %s has no matching '}': %s" % (self._lines.index(option)+1, start, option))
node = result[start+1:end]
if not node.lower() in self.nodes:
die("on line %s the node {%s} does not exist or has no options: %s" % (self._lines.index(option)+1, node, option))
result = result[:start] + self.expand_node(node) + result[end+1:]
return result
def validate(self):
for node in self.nodes:
for option in self.nodes[node]:
self.expand_option(option)
@staticmethod
def from_file(path):
grammar = Grammar()
node = "__root__"
for line in open(path):
line = line.strip()
grammar._lines.append(line)
if len(line) == 0:
continue # skip empty lines
if line[0] == "#":
continue # skip comments
if line[0] == "[" and line[-1] == "]":
node = line[1:-1]
else:
grammar.add_node_option(node.lower(), line)
grammar.validate()
return grammar
if __name__ == "__main__":
if len(sys.argv) != 2:
print >> sys.stderr, "Usage: %s grammarfile" % sys.argv[0]
exit(1)
grammar = Grammar.from_file(sys.argv[1])
print grammar.generate()