如今假设咱们须要解析以下的字符串,它由括号和英文字母组成: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']]]]