【问题标题】:Interpreter program parsing with Python like for Scheme (Lisp)?像 Scheme (Lisp) 这样的 Python 解释器程序解析?
【发布时间】:2015-08-20 10:57:12
【问题描述】:

像Scheme (Lisp) 这样的Python 解释器程序解析?

如何像使用 Scheme 一样使用 Python 解析程序?

使用Scheme,我为布尔表达式写了一些简单的BNF,其中AND表达式看起来像('and' ('lit' #t) ('lit' #f)),然后当我用Scheme阅读这个小程序时,我(免费)得到一个我可以使用list-refcar/cdr 处理的事情列表。

使用 Python 或 C 如何进行类似的解析?

【问题讨论】:

    标签: python python-3.x compiler-construction interpreter bnf


    【解决方案1】:

    对于 Python,有几个解析器/解析器生成器库。一个是pyparsing,网站上有一些示例。其中有一个simple boolean expression parser/evaluator

    #
    # simpleBool.py
    #
    # Example of defining a boolean logic parser using
    # the operatorGrammar helper method in pyparsing.
    #
    # In this example, parse actions associated with each
    # operator expression will "compile" the expression
    # into BoolXXX class instances, which can then
    # later be evaluated for their boolean value.
    #
    # Copyright 2006, by Paul McGuire
    # Updated 2013-Sep-14 - improved Python 2/3 cross-compatibility
    #
    from pyparsing import infixNotation, opAssoc, Keyword, Word, alphas
    
    # define classes to be built at parse time, as each matching
    # expression type is parsed
    class BoolOperand(object):
        def __init__(self,t):
            self.label = t[0]
            self.value = eval(t[0])
        def __bool__(self):
            return self.value
        def __str__(self):
            return self.label
        __repr__ = __str__
        __nonzero__ = __bool__
    
    class BoolBinOp(object):
        def __init__(self,t):
            self.args = t[0][0::2]
        def __str__(self):
            sep = " %s " % self.reprsymbol
            return "(" + sep.join(map(str,self.args)) + ")"
        def __bool__(self):
            return self.evalop(bool(a) for a in self.args)
        __nonzero__ = __bool__
        __repr__ = __str__
    
    class BoolAnd(BoolBinOp):
        reprsymbol = '&'
        evalop = all
    
    class BoolOr(BoolBinOp):
        reprsymbol = '|'
        evalop = any
    
    class BoolNot(object):
        def __init__(self,t):
            self.arg = t[0][1]
        def __bool__(self):
            v = bool(self.arg)
            return not v
        def __str__(self):
            return "~" + str(self.arg)
        __repr__ = __str__
        __nonzero__ = __bool__
    
    TRUE = Keyword("True")
    FALSE = Keyword("False")
    boolOperand = TRUE | FALSE | Word(alphas,max=1)
    boolOperand.setParseAction(BoolOperand)
    
    # define expression, based on expression operand and
    # list of operations in precedence order
    boolExpr = infixNotation( boolOperand,
        [
        ("not", 1, opAssoc.RIGHT, BoolNot),
        ("and", 2, opAssoc.LEFT,  BoolAnd),
        ("or",  2, opAssoc.LEFT,  BoolOr),
        ])
    
    
    if __name__ == "__main__":
        p = True
        q = False
        r = True
        tests = [("p", True),
                 ("q", False),
                 ("p and q", False),
                 ("p and not q", True),
                 ("not not p", True),
                 ("not(p and q)", True),
                 ("q or not p and r", False),
                 ("q or not p or not r", False),
                 ("q or not (p and r)", False),
                 ("p or q or r", True),
                 ("p or q or r and False", True),
                 ("(p or q or r) and False", False),
                ]
    
        print("p =", p)
        print("q =", q)
        print("r =", r)
        print()
        for t,expected in tests:
            res = boolExpr.parseString(t)[0]
            success = "PASS" if bool(res) == expected else "FAIL"
            print (t,'\n', res, '=', bool(res),'\n', success, '\n')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      • 2012-03-12
      • 2018-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多