简易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']]]]
相关文章
相关标签/搜索