Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.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 带pyparsing的级联三元运算符_Python_Pyparsing - Fatal编程技术网

Python 带pyparsing的级联三元运算符

Python 带pyparsing的级联三元运算符,python,pyparsing,Python,Pyparsing,使用pyparsing,我希望能够解析以下语法: 1?1:0?1:0 应将其理解为标准三元运算符条件?true\u part:false\u part,其中两个简单地连接在一起,因此第一个的结果构成第二个的条件 到目前为止,我有以下代码(简化): 将pyparsing导入为pp 三元中缀=pp.INFIX表示法( pp.pyu公共整数[ (((“?”,“:”)第3页,opAssoc.左), ]) 三元中缀.parseString(“1?1:0?1:0”,parseAll=True) 这将产生

使用pyparsing,我希望能够解析以下语法:

1?1:0?1:0
应将其理解为标准三元运算符
条件?true\u part:false\u part
,其中两个简单地连接在一起,因此第一个的结果构成第二个的条件

到目前为止,我有以下代码(简化):

将pyparsing导入为pp
三元中缀=pp.INFIX表示法(
pp.pyu公共整数[
(((“?”,“:”)第3页,opAssoc.左),
])
三元中缀.parseString(“1?1:0?1:0”,parseAll=True)
这将产生:

ParseException:预期的文本结尾(在字符5处),(行:1,列:6)

除非我在两个三元表达式中的一个周围添加括号,例如
“(1?1:0)?1:0”
“1?1:(0?1:0)”
都可以工作

但是,如果没有括号,我怎么能让它工作呢?基本上就是从左到右,以一种严格的左联想的方式来阅读

编辑:


很好地阅读了三元运算符的结合性工作原理:-结果是左assoc没有多大意义。然而,我试图模仿的语言实际上是从左到右处理这些表达式。

您可以尝试分别编写每个运算符

import pyparsing as pp

TERNARY_INFIX = pp.infixNotation(
    pp.pyparsing_common.integer, [
        (("?"), 2, pp.opAssoc.LEFT),
        ((":"), 2, pp.opAssoc.LEFT)
])

TERNARY_INFIX.parseString("1?1:0?1:0", parseAll=True)
输出:

[[[1, '?', 1], ':', [0, '?', 1], ':', 0]]

我认为这个操作符实际上是右联想的,不是左联想的。如果我将您的代码更改为:

import pyparsing as pp

TERNARY_INFIX = pp.infixNotation(
    pp.pyparsing_common.integer, [
        (("?", ":"), 3, pp.opAssoc.RIGHT),
])

TERNARY_INFIX.runTests("""\
1?1:(0?1:0)
(1?1:0)?1:0
1?1:0?1:0
""", fullDump=False)
然后我得到了合理的输出,没有参数的输入没有错误:

1?1:(0?1:0)
[[1, '?', 1, ':', [0, '?', 1, ':', 0]]]

(1?1:0)?1:0
[[[1, '?', 1, ':', 0], '?', 1, ':', 0]]

1?1:0?1:0
[[1, '?', 1, ':', [0, '?', 1, ':', 0]]]
下面是一个较大的表达式,用于计算3个变量中最大的一个(来自本C教程:):

编辑:我现在看到这与重复的二进制运算符类似,如“1+2+3”。左关联的pyparsing不会将它们解析为
[['1'+'2']'+'3']
,而只是
['1'+'2'+'3']
,由求值者进行重复的从左到右求值

当我添加三元运算符时,我没有设想像您正在解析的那种链式形式。将一行更改为
infixNotation
将成功解析具有左关联性的表达式,但与链式二进制运算符一样,会给出未分组的结果:

[1, '?', 1, ':', 0, '?', 1, ':', 0]
与重复添加示例一样,由评估者进行从左到右的连续评估,例如:

def eval_ternary(tokens):
    operands = tokens[0]
    ret = bool(operands[0])
    i = 1
    while i < len(operands):
        ret = bool(operands[i+1]) if ret else bool(operands[i+3])
        i += 4
    return ret
致:

在pyparsing.py中进行此更改,或者将
infxNotation
的定义复制到您自己的代码中并在其中进行更改

我将在pyparsing的下一版本中进行此更改


EDIT-在刚刚发布的pyparsing 2.4.6中修复。

是的,但我需要将每个三元运算符的3个操作数保持在一起,以便我的
parseAction
函数的
eval
工作。我将在问题中补充这一点……这是正确的答案,除非您正在解析PHP,它莫名其妙地有一个左关联三元运算符。更新我用另一个解析器测试过,我的解析器应该模仿它,它确实是左关联的。无论这是否有意义,但我需要它以完全相同的方式工作。:/所以问题仍然存在,为什么这个小小的改变会完全破坏解析器?这里将详细讨论三元运算符的左与右关联性:对不起,我之前没有注意到您的编辑。测试版本2.4.6和相应的计算器,它现在与我的左关联三元运算符完美结合。谢谢你的更新!:)
[1, '?', 1, ':', 0, '?', 1, ':', 0]
def eval_ternary(tokens):
    operands = tokens[0]
    ret = bool(operands[0])
    i = 1
    while i < len(operands):
        ret = bool(operands[i+1]) if ret else bool(operands[i+3])
        i += 4
    return ret
       elif arity == 3:
            matchExpr = _FB(
                lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr
            ) + Group(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr)
       elif arity == 3:
            matchExpr = _FB(
                lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr
            ) + Group(lastExpr + OneOrMore(opExpr1 + lastExpr + opExpr2 + lastExpr))
                                 ^^^^^^^^^^