Pyparsing 可选重复表达式的总和
Pyparsing sum of optionally repeated expressions
我正在开发一个简单的解析器来处理如下表达式:
"""
FOO*1.5
+
BAR*3
"""
要获得最终数值结果,其中 FOO
和 BAR
在运行时由外部函数执行返回的值替换。例如:FOO ---> def foo():return 2
和 BAR ---> def bar():return 4
。在我们的例子中会产生 (2*1.5)+(4*3) = 3+12 = 14
.
这是我目前拥有的:
from pyparsing import *
from decimal import Decimal
WEIGHT_OPERATORS = ['*', '/']
NUMERIC_OPERATORS = ['+', '-']
def make_score(input):
if input[0] == 'FOO':
return 5
elif input[0] == 'BAR':
return 10
return 1
def make_decimal(input):
try:
return Decimal(input[0])
except ValueError:
pass
return 0
SCORE = Word(alphanums + '_').setParseAction(make_score)
WEIGHT_OPERATOR = oneOf(WEIGHT_OPERATORS)
WEIGHT = Word(nums+'.').setParseAction(make_decimal)
INDIVIDUAL_EXPRESSION = SCORE('score') \
+ WEIGHT_OPERATOR('weight_operator') \
+ WEIGHT('weight')
print INDIVIDUAL_EXPRESSION
print INDIVIDUAL_EXPRESSION.parseString(expression).dump()
到目前为止,一切正常。
我想念的是 "chain" INDIVIDUAL_EXPRESSIONs 到 add/substract 的能力,就像上面的简单示例一样。我试过:
GLOBAL_EXPRESSION = infixNotation(
INDIVIDUAL_EXPRESSION,
[
(NUMERIC_OPERATORS, 2, opAssoc.RIGHT,)
# or (NUMERIC_OPERATORS, 1, opAssoc.LEFT,), etc... :(
]
)
print GLOBAL_EXPRESSION
print GLOBAL_EXPRESSION.parseString(expression).dump()
没有。
并且:
INDIVIDUAL_EXPRESSION = SCORE('score') \
+ WEIGHT_OPERATOR('weight_operator') \
+ WEIGHT('weight')
+ ZeroOrMore(NUMERIC_OPERATORS)
想得到最终容易计算的list或dict,无果。我做错了什么,但是什么?
试试这个:
GLOBAL_EXPRESSION = OneOrMore(Group(INDIVIDUAL_EXPRESSION) + Optional(oneOf(NUMERIC_OPERATORS)))
GE_LIST = Group(delimitedList(GLOBAL_EXPRESSION))
print GE_LIST.parseString(expression)
我正在开发一个简单的解析器来处理如下表达式:
"""
FOO*1.5
+
BAR*3
"""
要获得最终数值结果,其中 FOO
和 BAR
在运行时由外部函数执行返回的值替换。例如:FOO ---> def foo():return 2
和 BAR ---> def bar():return 4
。在我们的例子中会产生 (2*1.5)+(4*3) = 3+12 = 14
.
这是我目前拥有的:
from pyparsing import *
from decimal import Decimal
WEIGHT_OPERATORS = ['*', '/']
NUMERIC_OPERATORS = ['+', '-']
def make_score(input):
if input[0] == 'FOO':
return 5
elif input[0] == 'BAR':
return 10
return 1
def make_decimal(input):
try:
return Decimal(input[0])
except ValueError:
pass
return 0
SCORE = Word(alphanums + '_').setParseAction(make_score)
WEIGHT_OPERATOR = oneOf(WEIGHT_OPERATORS)
WEIGHT = Word(nums+'.').setParseAction(make_decimal)
INDIVIDUAL_EXPRESSION = SCORE('score') \
+ WEIGHT_OPERATOR('weight_operator') \
+ WEIGHT('weight')
print INDIVIDUAL_EXPRESSION
print INDIVIDUAL_EXPRESSION.parseString(expression).dump()
到目前为止,一切正常。
我想念的是 "chain" INDIVIDUAL_EXPRESSIONs 到 add/substract 的能力,就像上面的简单示例一样。我试过:
GLOBAL_EXPRESSION = infixNotation(
INDIVIDUAL_EXPRESSION,
[
(NUMERIC_OPERATORS, 2, opAssoc.RIGHT,)
# or (NUMERIC_OPERATORS, 1, opAssoc.LEFT,), etc... :(
]
)
print GLOBAL_EXPRESSION
print GLOBAL_EXPRESSION.parseString(expression).dump()
没有。
并且:
INDIVIDUAL_EXPRESSION = SCORE('score') \
+ WEIGHT_OPERATOR('weight_operator') \
+ WEIGHT('weight')
+ ZeroOrMore(NUMERIC_OPERATORS)
想得到最终容易计算的list或dict,无果。我做错了什么,但是什么?
试试这个:
GLOBAL_EXPRESSION = OneOrMore(Group(INDIVIDUAL_EXPRESSION) + Optional(oneOf(NUMERIC_OPERATORS)))
GE_LIST = Group(delimitedList(GLOBAL_EXPRESSION))
print GE_LIST.parseString(expression)