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
    """
  • 相关阅读:
    微信小程序HTTPS
    微信商城-1简介
    va_list
    Event log c++ sample.
    EVENT LOGGING
    Analyze Program Runtime Stack
    unknow table alarmtemp error when drop database (mysql)
    This application has request the Runtime to terminate it in an unusual way.
    How to check if Visual Studio 2005 SP1 is installed
    SetUnhandledExceptionFilter
  • 原文地址:https://www.cnblogs.com/namejr/p/10004649.html
Copyright © 2011-2022 走看看