使用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方式从左向右阅读?
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']]]
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]]