具有pyparsing的级联三元运算符

问题描述 投票:1回答:2

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

1?1:0?1:0

应该被理解为标准三元运算符condition ? true_part : false_part,其中两个简单地串联在一起,因此第一个的结果成为第二个的条件。

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

import pyparsing as pp

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

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

哪个产量:

ParseException:预期的文本结尾(在char 5),(第1行,col:6)

除非我在两个三元表达式之一之间加上括号,所以例如"(1?1:0)?1:0""1?1:(0?1:0)"有效。

但是但是如何在没有括号的情况下使它正常工作,基本上只能以严格的[[left-associative方式从左向右阅读?

python pyparsing
2个回答
2
投票
我认为此运算符实际上是右联想,而不是左联想。如果我将您的代码更改为:

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教程:http://cprogramming.language-tutorial.com/2012/01/biggest-of-3-numbers-using-ternary.html):

TERNARY = pp.infixNotation( pp.Char("abc"), [ (pp.oneOf("> <"), 2, pp.opAssoc.LEFT), (("?", ":"), 3, pp.opAssoc.RIGHT), ]) TERNARY.runTests("""\ (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c) a > b ? a > c ? a : c : b > c ? b : c """, fullDump=False)

给予:

(a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c) [[['a', '>', 'b'], '?', [['a', '>', 'c'], '?', 'a', ':', 'c'], ':', [['b', '>', 'c'], '?', 'b', ':', 'c']]] a > b ? a > c ? a : c : b > c ? b : c [[['a', '>', 'b'], '?', [['a', '>', 'c'], '?', 'a', ':', 'c'], ':', [['b', '>', 'c'], '?', 'b', ':', 'c']]]


1
投票
您可以尝试分别编写每个运算符。

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]]

© www.soinside.com 2019 - 2024. All rights reserved.