zoukankan      html  css  js  c++  java
  • 干货-递归下降分析器 笔记(具体看Python Cookbook, 3rd edition 的2.19章节)

    import re
    import collections
    # 写将要匹配的正则
    NUM = r'(?P<NUM>d+)'
    PLUS = r'(?P<PLUS>+)'
    MINUS = r'(?P<MINUS>-)'
    TIMES = r'(?P<TIMES>*)'
    DIVIDE = r'(?P<DIVIDE>/)'
    LPAREN = r'(?P<LPAREN>()'
    RPAREN = r'(?P<RPAREN>))'
    WS = r'(?P<WS>s+)'
    # 构建compile()对象
    master_pat = re.compile('|'.join([NUM, PLUS, MINUS, TIMES, DIVIDE, LPAREN, RPAREN, WS]))
    
    # 构建一个生成器
    def gennerate_tokens(text):
        Token = collections.namedtuple('Token', ['type', 'value'])  # 构建一个元组
        scanner = master_pat.scanner(text)  # 创建scanner()对象
        # 进行扫描
        for m in iter(scanner.match, None):
            tok = Token(m.lastgroup, m.group())  # 添加元组
            if tok.type != 'WS':
                yield tok
    
    class ExpressionEvaluator(object):
        def parse(self, text):
            self.tokens = gennerate_tokens(text)
            self.tok = None
            self.nexttok = None
            self._advance()
            return self.expr()
        def _advance(self):
            # 进行往下移动
            self.tok, self.nexttok = self.nexttok, next(self.tokens, None)
        def _accept(self, toktype):
            # 判断下一个节点的类型是否正确
            if self.nexttok and self.nexttok.type == toktype:
                self._advance()  # 如果节点类型正确,那么就往下一个节点
                return True
            else:
                return False
        def _except(self, toktype):
            # 用来判断是否是理想环境(如括号是否封闭)
            if not self._accept(toktype):
                raise SyntaxError('Excepted' + toktype)
        def expr(self):
            """ 进行加减操作 """
            exprval = self.term()
            while self._accept('PLUS') or self._accept('MINUS'):
                op = self.tok.type  # 获取当前操作类型
                right = self.term()  # 先计算右边部分
                if op == 'PLUS':
                    exprval += right
                elif op == 'MINUS':
                    exprval -= right
            return exprval
        def term(self):
            """ 进行乘除操作 """
            termval = self.factor()
            while self._accept('TIMES') or self._accept('DIVIDE'):
                op = self.tok.type  # 获取当前操作
                right = self.factor()  # 计算右边部分
                if op == 'TIMES':
                    termval *= right
                elif op == 'DIVIDE':
                    termval /= right
            return termval
        def factor(self):
            if self._accept('NUM'):
                return int(self.tok.value)
            elif self._accept('LPAREN'):
                exprval = self.expr()
                self._except('RPAREN')
                return exprval
            else:
                raise SyntaxError("Excepted NUMBER or LPAREN...")
    
    def descent_parser():
        e = ExpressionEvaluator()
        print(e.parse('2'))
        print(e.parse('2 + 3'))
        print(e.parse('2 - 3'))
        print(e.parse('2 + 3 * 5'))
        print(e.parse('4 - 6 / 2'))
        print(e.parse('2 + (3 + 1)/2'))
    
    # 入口函数
    if __name__ == "__main__":
        descent_parser()
    """
    D:笔记python电子书Python3>python index.py
    2
    5
    -1
    17
    1.0
    4.0
    """
  • 相关阅读:
    PAT (Advanced Level) 1114. Family Property (25)
    PAT (Advanced Level) 1113. Integer Set Partition (25)
    PAT (Advanced Level) 1112. Stucked Keyboard (20)
    PAT (Advanced Level) 1111. Online Map (30)
    PAT (Advanced Level) 1110. Complete Binary Tree (25)
    PAT (Advanced Level) 1109. Group Photo (25)
    PAT (Advanced Level) 1108. Finding Average (20)
    PAT (Advanced Level) 1107. Social Clusters (30)
    PAT (Advanced Level) 1106. Lowest Price in Supply Chain (25)
    PAT (Advanced Level) 1105. Spiral Matrix (25)
  • 原文地址:https://www.cnblogs.com/namejr/p/10004649.html
Copyright © 2011-2022 走看看