-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconcat.py
executable file
·124 lines (107 loc) · 3.52 KB
/
concat.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
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
120
121
122
123
#!/usr/bin/env python3
import sys
from lark import Lark
from lark import Transformer
from functools import reduce
# https://www.asciiart.eu/animals/cats
grammar = '''
concat : cat | tac | ball | container | brace | paren | adjacent | multiple | over | group
group : "<" concat ">"
over : concat [ "/" concat ]
multiple : concat "*" /[0-9]+/
adjacent : concat [ "+" concat ]
paren : "(" [ concat ] ")"
brace : "{" [ concat ] "}"
container : "[" [ concat ] "]"
ball : "@"
tac : "tac"
cat : "cat"
%import common.WS
%ignore WS
'''
class T(Transformer):
def concat(self, tree):
return tree
def group(self, tree): # <>
return tree[0][0]
def over(self, tree): # /
at = tree[0][0].split('\n'); wt = len(at[0])
ab = tree[1][0].split('\n'); wb = len(ab[0])
at = list(map(lambda x: (x + ' ' * (wb - wt)), at))
ab = list(map(lambda x: (x + ' ' * (wt - wb)), ab))
return '\n'.join(at + ab)
def multiple(self, tree): # *
l = tree[0] * int(tree[1])
return reduce(lambda x, y: self.adjacent([[x], [y]]), l)
def adjacent(self, tree): # +
al = tree[0][0].split('\n'); wl = len(al[0]); hl = len(al)
ar = tree[1][0].split('\n'); wr = len(ar[0]); hr = len(ar)
al = ([' ' * wl] * (hr - hl)) + al
ar = ([' ' * wr] * (hl - hr)) + ar
a = list(map(' '.join, zip(al, ar)))
return '\n'.join(a)
def paren(self, tree): # ()
a = tree[0][0].split('\n') if len(tree) else [' ' * 8] * 4
w = len(a[0])
a.insert(0, ' ' + ('~' * w) + ' ') # 0
a.append( ' ' + ('~' * w) + ' ') # -1
a[ 1] = ' (' + a[ 1] + ') '
a[2:-2] = map(lambda x: f'( {x} )', a[2:-2])
a[-2] = ' (' + a[-2] + ') '
return '\n'.join(a)
# ~~~~~~~~ 0
# ( /\ /) 1
# ( (' ) ( ) 2:-2
# ( ( \ ) ) 2:-2
# ( |(__)/ ) -2
# ~~~~~~~~ -1
def brace(self, tree): # {}
a = tree[0][0].split('\n') if len(tree) else [' ' * 8] * 4
w = len(a[0])
a.insert(0, ' ' + ('-' * w) + ' ') # 0
a.append(' \\' + ('_' * (w - 1)) + '/ ') # -1
a[1] = ' /' + a[1] + '\\ '
a[2] = '/ ' + a[2] + ' |'
a[3:-2] = map(lambda x: f'| {x} |', a[3:-2])
a[-2] = ' \\' + a[-2] + ' |'
return '\n'.join(a)
# ________ 0
# / /\ /\ 1
# / (' ) ( | 2
# | ( \ ) | 3:-2
# \ |(__)// | -2
# \_______/ -1
def container(self, tree): # []
a = tree[0][0].split('\n') if len(tree) else [' ' * 8] * 4
w = len(a[0])
a = list(map(lambda x: f'|{x}|', a))
a.insert(0, ' ' + '-' * w + ' ')
a.append( ' ' + '-' * w + ' ')
return '\n'.join(a)
def ball(self, tree):
return \
r" " + "\n" + \
r" " + "\n" + \
r" __ " + "\n" + \
r" _/ \_@"
def tac(self, tree):
return \
r"\ /\ " + "\n" + \
r" ) ( ')" + "\n" + \
r"( / ) " + "\n" + \
r" \(__)| "
def cat(self, tree):
return \
r" /\ /" + "\n" + \
r"(' ) ( " + "\n" + \
r" ( \ )" + "\n" + \
r" |(__)/ "
def main():
text = sys.argv[1]
parser = Lark(grammar, start='concat')
tree = parser.parse(text)
#print(tree.pretty()) # debug
result = T().transform(tree)[0]
print(result)
if __name__ == '__main__':
main()