new file 100644
from abc import abstractmethod
class Token:
is_skippable = False
@abstractmethod
def list_first(self):
pass
def list_last(self):
def list_neighbours(self):
class Symbol(Token):
def __init__(self, position, value):
self.position = position
self.value = value
yield self.position
yield from []
def __str__(self):
return self.value
class Asterisk(Token):
is_skippable = True
def __init__(self, content: Token):
self.content = content
yield from self.content.list_first()
yield from self.content.list_last()
yield from self.content.list_neighbours()
for x in self.list_last():
for y in self.list_first():
yield (x, y)
return str(self.content) + "*"
class Chain(Token):
def __init__(self, content: list):
for token in self.content:
yield from token.list_first()
if not token.is_skippable:
break
for token in reversed(self.content):
yield from token.list_last()
previous = []
for t in previous:
for x in t.list_last():
for y in token.list_first():
yield from token.list_neighbours()
if token.is_skippable:
previous.append(token)
else:
previous = [token]
return "(" + "".join(str(x) for x in self.content) + ")"
def find_closing_parenthesis(pattern, k):
counter = 0
for (i, c) in enumerate(pattern[k:]):
if c == "(":
counter += 1
elif c == ")":
counter -= 1
if counter == 0:
return k+i
return None
def parse(pattern, offset=0):
res = []
i = 0
while i < len(pattern):
c = pattern[i]
j = find_closing_parenthesis(pattern, i)
inner_content = parse(pattern[i+1:j], offset+i+1)
res.append(inner_content)
i = j+1
elif c == "*":
token = res.pop()
res.append(Asterisk(token))
i += 1
res.append(Symbol(i+offset, c))
return Chain(res)
if __name__ == "__main__":
for pattern in ["a*b*", "(ab)*", "a((bc)*d)*"]:
print("#", pattern)
p = parse(pattern)
print(p, list(p.list_first()), list(p.list_last()))
print(list(p.list_neighbours()))
print()
Status change: