如今假設咱們須要解析以下的字符串,它由括號和英文字母組成:python
abcd(awef(af)(32d)(sdf(sdf)))
咱們但願遇到括號就作成list嵌套list的形式。一個辦法是一個一個字符遍歷,但值得注意的是,字符串裏邊英文字母和數字不是固定長度的,後面遇到複雜的解析還得考慮數字、空格、換行等複雜狀況,這給咱們帶來困擾。因此,咱們應該考慮先把字符串進行分詞,變成以下的形式:bash
['abcd', '(', 'awef', '(', 'af', ')', '(', '32d', ')', '(', 'sdf', '(', 'sdf', ')', ')']
這樣分詞之後,list裏邊就是一個一個元素單元,再進行遍歷就方便不少。因此,咱們如何構造一個這樣的分詞器呢?它將不一樣單詞隔開的依據是什麼?固然是由於它們不屬於一個元素。在這裏,問題較爲簡單,不一樣元素之間是經過)和(號進行隔開的,咱們只須要遇到這2個符號進行分隔就OK了。分隔字符串通常是從起始位置到結束位置,例如abcd是從0分割點到4號分割點(即str[0:4]),而第一個(號是從4號到5號分割點(即str[4:5]),具體能夠用下圖表示:app
整個字符串咱們都要遍歷,那麼確定有一個for循環。在循環中,咱們很容易獲得當前位置i,假設循環到str[4] == '(',那麼咱們應該分割str[0:4],而循環到str[5] == 'a'的時候,咱們應該分割str[4:5]。如今咱們能夠初步構建這個循環:code
def parse_go(str_in): search_dict = {"(": 'left', ")": 'right'} save_list = [] pos = 0 last_state = search_dict.get(str_in[0], 'En') for i, c in enumerate(str_in): curr_state = search_dict.get(c, 'En') if curr_state != last_state: save_list.append((str_in[self.pos:i], last_state)) pos = i last_state = curr_state return save_list
接下來咱們對分詞好的save_list進行下一步處理,迭代構造AST。這裏咱們用list套list的形式構造:blog
pos = 0 def iter_search(ele_list): # type:(list, Parser1) -> list tmp_list = [] while pos < len(ele_list): ele = ele_list[pos] type_t = ele.type if type_t == 'left': pos += 1 tmp_list.append(iter_search(ele_list)) elif type_t == 'right': pos += 1 break else: tmp_list.append(ele.val) pos += 1 return tmp_list
最後的效果示意:字符串
['abcd', ['awef', ['af'], ['32d'], ['sdf', ['sdf']]]]