Some general pyparsing tips:
Or(expr, empty)
is better written as Optional(expr)
. Also, your Or expression was trying to create an Or with the class Empty, you probably meant to write Empty()
or empty
for the second argument.
expr.setResultsName("name")
can now be written as expr("name")
If you want to apply structure to your results, use Group
.
Use dump()
instead of asDict()
to better view the structure of your parsed results.
Here is how I would build up your expression:
from pyparsing import Word, nums, oneOf, Combine, Group, Optional
integer = Word(nums)
sign = oneOf("+ -")
signedInteger = Combine(sign + integer)
integerExpr = Group(integer("base") + Optional(signedInteger, default="0")("offset"))
integerRange = integerExpr("start") + Optional('_' + integerExpr("end"))
tests = """\
12
12+34
12_56
12+34_56-78""".splitlines()
for t in tests:
result = integerRange.parseString(t)
print t
print result.dump()
print result.asDict()
print result.start.base, result.start.offset
if result.end:
print result.end.base, result.end.offset
print
Prints:
12
[['12', '0']]
- start: ['12', '0']
- base: 12
- offset: 0
{'start': (['12', '0'], {'base': [('12', 0)], 'offset': [('0', 1)]})}
12 0
12+34
[['12', '+34']]
- start: ['12', '+34']
- base: 12
- offset: +34
{'start': (['12', '+34'], {'base': [('12', 0)], 'offset': [('+34', 1)]})}
12 +34
12_56
[['12', '0'], '_', ['56', '0']]
- end: ['56', '0']
- base: 56
- offset: 0
- start: ['12', '0']
- base: 12
- offset: 0
{'start': (['12', '0'], {'base': [('12', 0)], 'offset': [('0', 1)]}), 'end': (['56', '0'], {'base': [('56', 0)], 'offset': [('0', 1)]})}
12 0
56 0
12+34_56-78
[['12', '+34'], '_', ['56', '-78']]
- end: ['56', '-78']
- base: 56
- offset: -78
- start: ['12', '+34']
- base: 12
- offset: +34
{'start': (['12', '+34'], {'base': [('12', 0)], 'offset': [('+34', 1)]}), 'end': (['56', '-78'], {'base': [('56', 0)], 'offset': [('-78', 1)]})}
12 +34
56 -78