美文网首页
词法分析、语法分析专题

词法分析、语法分析专题

作者: madao756 | 来源:发表于2020-05-30 20:03 被阅读0次

    词法分析、语法分析专题

    前言:这是字符串解析的大杀器,基本上能推出「上下文无关文法」就能做出这道题

    0X00 模板

    1096. 花括号展开 II

    转:https://leetcode-cn.com/problems/brace-expansion-ii/solution/pythondi-gui-xia-jiang-yu-fa-fen-xi-yi-chong-fan-2/

    import re
    from collections import namedtuple
    
    token = namedtuple('token', ['type', 'value'])
    
    
    left = r'(?P<LEFT>\{)'
    right = r'(?P<RIGHT>\})'
    word = r'(?P<WORD>[a-z]+)'
    comma = r'(?P<COMMA>\,)'
    blank = r'(?P<BLANK>\s)'
    pt = re.compile('|'.join([left, right, word, comma, blank]))
    
    
    def genToken(s):
        scanner = pt.scanner(s)
        for i in iter(scanner.match, None):
            if i.lastgroup != 'BLANK':
                yield token(i.lastgroup, i.group(0))
    
    
    class parser:
        '''gramar
            expr -> item | item ',' expr
            item -> factor | factor item
            factor -> WORD | '{' expr '}'
        '''
    
        def match(self, tp):
            # print(self.p.value)
            if tp == self.p.type:
                val = self.p.value
                try:
                    self.p = next(self.gen)
                except StopIteration:
                    self.p = None
                except Exception as e:
                    print(e)
                return val
            else:
                raise Exception(f"[Error]: {tp} expected, got {self.p.type}")
    
        def parse(self, s):
            self.gen = genToken(s)
            self.p = next(self.gen)
            st = self.expr()
            return sorted(list(st))
    
        def expr(self):
            ret = self.item()
            while self.p and self.p.type == 'COMMA':
                self.match('COMMA')
                ret = ret.union(self.item())
            return ret
    
        def item(self):
            ret = self.factor()
            while self.p and self.p.type in ['WORD', 'LEFT']:
                sufs = self.factor()
                new = set()
                for pre in ret:
                    for suf in sufs:
                        new.add(pre+suf)
                ret = new
            return ret
    
        def factor(self):
            if self.p.type == 'LEFT':
                self.match('LEFT')
                ret = self.expr()
                self.match('RIGHT')
                return ret
            return {self.match('WORD')}
    
    
    class Solution:
        def braceExpansionII(self, expression):
            return parser().parse(expression)
    
    
    if __name__ == '__main__':
        sol = Solution()
        li = ["{a,b}{c{d,e}}", "{{a,z}, a{b,c}, {ab,z}}", "{a,b}c{d,e}f"]
        for i in li:
            print('>>>', i)
            print(sol.braceExpansionII(i))
    

    我基本上写完这一套要 20min 哭了。。。

    对于「上下文无关文法」的推导的关键是凑反正从 expr 开始,一般两三层可以搞定。

    0X01 相关题目

    相关文章

      网友评论

          本文标题:词法分析、语法分析专题

          本文链接:https://www.haomeiwen.com/subject/ptihzhtx.html