import re
test = """import (
"github.com/user/qrt"
"fmt"
"github.com/user/zyx"
)
import "abcdef"
import "abzdef"
"""
BEGIN = 1
IMPORT = 2
DESCENT = 3
class Lexer(object):
def __init__(self, text):
self._rx = re.compile(r'(import|".*?"|\(|\))')
self._text = text
def __iter__(self):
for m in self._rx.finditer(self._text):
yield m.group(1)
class RecursiveDescent(object):
state = BEGIN
def __init__(self, lexer):
self._lexer = lexer
def __iter__(self):
for token in self._lexer:
if self.state == BEGIN:
if token != 'import':
# Beginning of the program most likely
raise StopIteration
self.state = IMPORT
elif self.state == IMPORT:
if token == '(':
self.state = DESCENT
else:
self.state = BEGIN
yield token
elif self.state == DESCENT:
if token == ')':
self.state = BEGIN
else:
yield token
for path in RecursiveDescent(Lexer(test)):
print(path)
aW1wb3J0IHJlCgp0ZXN0ID0gIiIiaW1wb3J0ICgKICAgICJnaXRodWIuY29tL3VzZXIvcXJ0IgoKICAgICJmbXQiCgogICAgImdpdGh1Yi5jb20vdXNlci96eXgiCikKCmltcG9ydCAiYWJjZGVmIgoKaW1wb3J0ICJhYnpkZWYiCiIiIgoKQkVHSU4gPSAxCklNUE9SVCA9IDIKREVTQ0VOVCA9IDMKCgpjbGFzcyBMZXhlcihvYmplY3QpOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHRleHQpOgogICAgICAgIHNlbGYuX3J4ID0gcmUuY29tcGlsZShyJyhpbXBvcnR8Ii4qPyJ8XCh8XCkpJykKICAgICAgICBzZWxmLl90ZXh0ID0gdGV4dAoKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICBmb3IgbSBpbiBzZWxmLl9yeC5maW5kaXRlcihzZWxmLl90ZXh0KToKICAgICAgICAgICAgeWllbGQgbS5ncm91cCgxKQoKCmNsYXNzIFJlY3Vyc2l2ZURlc2NlbnQob2JqZWN0KToKICAgIHN0YXRlID0gQkVHSU4KCiAgICBkZWYgX19pbml0X18oc2VsZiwgbGV4ZXIpOgogICAgICAgIHNlbGYuX2xleGVyID0gbGV4ZXIKCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgZm9yIHRva2VuIGluIHNlbGYuX2xleGVyOgogICAgICAgICAgICBpZiBzZWxmLnN0YXRlID09IEJFR0lOOgogICAgICAgICAgICAgICAgaWYgdG9rZW4gIT0gJ2ltcG9ydCc6CiAgICAgICAgICAgICAgICAgICAgIyBCZWdpbm5pbmcgb2YgdGhlIHByb2dyYW0gbW9zdCBsaWtlbHkKICAgICAgICAgICAgICAgICAgICByYWlzZSBTdG9wSXRlcmF0aW9uCiAgICAgICAgICAgICAgICBzZWxmLnN0YXRlID0gSU1QT1JUCiAgICAgICAgICAgIGVsaWYgc2VsZi5zdGF0ZSA9PSBJTVBPUlQ6CiAgICAgICAgICAgICAgICBpZiB0b2tlbiA9PSAnKCc6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IERFU0NFTlQKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IEJFR0lOCiAgICAgICAgICAgICAgICAgICAgeWllbGQgdG9rZW4KICAgICAgICAgICAgZWxpZiBzZWxmLnN0YXRlID09IERFU0NFTlQ6CiAgICAgICAgICAgICAgICBpZiB0b2tlbiA9PSAnKSc6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IEJFR0lOCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHlpZWxkIHRva2VuCgpmb3IgcGF0aCBpbiBSZWN1cnNpdmVEZXNjZW50KExleGVyKHRlc3QpKToKICAgIHByaW50KHBhdGgpCg==