簡易Parser入門【二】:解析簡單的字符串,括號套括號形式

如今假設咱們須要解析以下的字符串,它由括號和英文字母組成: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']]]]
相關文章
相關標籤/搜索