Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带py解析的递归表达式_Python_Parsing_Pyparsing_Associativity - Fatal编程技术网

Python 带py解析的递归表达式

Python 带py解析的递归表达式,python,parsing,pyparsing,associativity,Python,Parsing,Pyparsing,Associativity,我试图找出如何在递归(不包含在任何内容中)表达式可能存在的情况下执行左关联表达式。例如,我想做: expr + OP + expr 它将像1x2x3这样的2个操作解析为(expr OP expr)OP expr结果 如果我试图阻止expr解析无限递归,我可以执行以下操作: expr -> Group(simple_expr + OP + expr) | simple_expr 然后我会得到expr OP(expr或expr)结果 如何强制左侧绑定 编辑:我知道有关运算符Re

我试图找出如何在递归(不包含在任何内容中)表达式可能存在的情况下执行左关联表达式。例如,我想做:

expr + OP + expr
它将像
1x2x3
这样的2个操作解析为
(expr OP expr)OP expr
结果

如果我试图阻止
expr
解析无限递归,我可以执行以下操作:

expr -> Group(simple_expr + OP + expr)
      | simple_expr
然后我会得到
expr OP(expr或expr)
结果

如何强制左侧绑定


编辑:我知道有关
运算符Recessence
的信息,但当运算符为
“is”+可选(“NOT”)
或类似值时,它似乎没有正确匹配。

Pyparsing生成左解析树。添加语义操作以在解析
expr
后立即编辑解析树。

下面是一个示例解析操作,它将获取标记的平面列表,并将它们嵌套,就像左递归解析一样:

from pyparsing import *

# parse action -maker
def makeLRlike(numterms):
    if numterms is None:
        # None operator can only by binary op
        initlen = 2
        incr = 1
    else:
        initlen = {0:1,1:2,2:3,3:5}[numterms]
        incr = {0:1,1:1,2:2,3:4}[numterms]

    # define parse action for this number of terms,
    # to convert flat list of tokens into nested list
    def pa(s,l,t):
        t = t[0]
        if len(t) > initlen:
            ret = ParseResults(t[:initlen])
            i = initlen
            while i < len(t):
                ret = ParseResults([ret] + t[i:i+incr])
                i += incr
            return ParseResults([ret])
    return pa


# setup a simple grammar for 4-function arithmetic
varname = oneOf(list(alphas))
integer = Word(nums)
operand = integer | varname

# ordinary opPrec definition
arith1 = operatorPrecedence(operand,
    [
    (None, 2, opAssoc.LEFT),
    (oneOf("* /"), 2, opAssoc.LEFT),
    (oneOf("+ -"), 2, opAssoc.LEFT),
    ])

# opPrec definition with parseAction makeLRlike
arith2 = operatorPrecedence(operand,
    [
    (None, 2, opAssoc.LEFT, makeLRlike(None)),
    (oneOf("* /"), 2, opAssoc.LEFT, makeLRlike(2)),
    (oneOf("+ -"), 2, opAssoc.LEFT, makeLRlike(2)),
    ])

# parse a few test strings, using both parsers
for arith in (arith1, arith2):
    print arith.parseString("A+B+C+D+E")[0]
    print arith.parseString("A+B+C*D+E")[0]
    print arith.parseString("12AX+34BY+C*5DZ+E")[0]
(类似LR)

['A', '+', 'B', '+', 'C', '+', 'D', '+', 'E']
['A', '+', 'B', '+', ['C', '*', 'D'], '+', 'E']
[['12', 'A', 'X'], '+', ['34', 'B', 'Y'], '+', ['C', '*', ['5', 'D', 'Z']], '+', 'E']
[[[['A', '+', 'B'], '+', 'C'], '+', 'D'], '+', 'E']
[[['A', '+', 'B'], '+', ['C', '*', 'D']], '+', 'E']
[[[[['12', 'A'], 'X'], '+', [['34', 'B'], 'Y']], '+', ['C', '*', [['5', 'D'], 'Z']]], '+', 'E']