Good morning,
I'm trying to parse numbers, both in decimal and hexadecimal format, and I need to return their radix.
My problem is that the ParseResults objects passed to my parseAction does nto have the attribute hex or dec as i specify.
Here is my code:
def processParsedNum(results):
'''
Process a ParsingResults objects resulting from parsing a number
@param results: the object containing all the parsed tokens
@return a stringified version of the parsed number
'''
#Process value
val = results.value
radix = 10
rawValue = results.value
#Process radix
strValue = None
if results.dec:
strValue = val.dec
elif results.hex:
strValue = "0x" + val.hex
results = 16
#Process prefix
if results.prefix:
strValue = results.prefix + strValue
results = strValue
results = radix
results = rawValue
return results
#HEXADECIMAL number may have either the prefix . or the h,H suffixes
NUM_HEX = Or([Suppress(Literal(".")) + Word(nums+"ABCDEF"+"abcdef"), \
Word(nums+"ABCDEF"+"abcdef") + Suppress(oneOf("H h"))])
NUM_HEX.setResultsName('hex')
NUM = Optional(SYMBOL).setResultsName('prefix') + \
Or().setResultsName('value')
NUM
NUM.setParseAction(processParsedNum)
I don't know what i'm doing wrong (of course i'm doing something), but i guess there should be a way of navigating through the parsed elements and it sub-elements.
Thanks in advance.
Cheers!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sorry to not see your post earlier. The problem is in the somewhat misleading function name "setResultsName". This method does not just set the return name, but returns a copy of the original expression. The reason for this is that a single expression might occur several times in a larger parser, with different results names associated with it.
In your parser, the solution is to simply assign the value returned by setResultsName back to the expression itself:
There is a shortened form of setResultsName which is useful when building up a larger expression from smaller ones.
NUM_DEC = NUM_DEC('dec')
NUM_HEX = NUM_HEX('hex')
Otherwise, your pyparsing parser code looks fine. With these changes, I was able to get your parser working with test strings "100", ".100", and "100h". You have a few remaining minor bugs in your parse action, here is a working version:
def processParsedNum(results):
'''
Process a ParsingResults objects resulting from parsing a number
@param results: the object containing all the parsed tokens
@return a stringified version of the parsed number
'''
#Process value
val = results.value
radix = 10
rawValue = results.value
#Process radix
strValue = None
if results.dec:
strValue = results.dec
elif results.hex:
strValue = "0x" + results.hex
radix = 16
#Process prefix
if results.prefix:
strValue = results.prefix + strValue
results['value'] = strValue
results['radix'] = radix
results['rawValue'] = rawValue
return results
Sorry for the delay, good luck in your parsing endeavors!
- Paul McGuire
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Good morning,
I'm trying to parse numbers, both in decimal and hexadecimal format, and I need to return their radix.
My problem is that the ParseResults objects passed to my parseAction does nto have the attribute hex or dec as i specify.
Here is my code:
def processParsedNum(results):
'''
Process a ParsingResults objects resulting from parsing a number
@param results: the object containing all the parsed tokens
@return a stringified version of the parsed number
'''
#Process value
val = results.value
radix = 10
rawValue = results.value
#Process radix
strValue = None
if results.dec:
strValue = val.dec
elif results.hex:
strValue = "0x" + val.hex
results = 16
#Process prefix
if results.prefix:
strValue = results.prefix + strValue
results = strValue
results = radix
results = rawValue
return results
#Decimal numbers
SYMBOL = oneOf('+ -')
NUM_INT = Word(nums)
NUM_FLOAT = Combine(NUM_INT + Literal(".") + NUM_INT, adjacent=True)
NUM_EXPONENTIAL = Combine(Or() + \
oneOf("E e") + \
Optional(SYMBOL) + \
NUM_INT, \
adjacent=True)
NUM_DEC = Or()
NUM_DEC.setResultsName('dec')
#HEXADECIMAL number may have either the prefix . or the h,H suffixes
NUM_HEX = Or([Suppress(Literal(".")) + Word(nums+"ABCDEF"+"abcdef"), \
Word(nums+"ABCDEF"+"abcdef") + Suppress(oneOf("H h"))])
NUM_HEX.setResultsName('hex')
NUM = Optional(SYMBOL).setResultsName('prefix') + \
Or().setResultsName('value')
NUM
NUM.setParseAction(processParsedNum)
I don't know what i'm doing wrong (of course i'm doing something), but i guess there should be a way of navigating through the parsed elements and it sub-elements.
Thanks in advance.
Cheers!
Sorry to not see your post earlier. The problem is in the somewhat misleading function name "setResultsName". This method does not just set the return name, but returns a copy of the original expression. The reason for this is that a single expression might occur several times in a larger parser, with different results names associated with it.
In your parser, the solution is to simply assign the value returned by setResultsName back to the expression itself:
There is a shortened form of setResultsName which is useful when building up a larger expression from smaller ones.
Otherwise, your pyparsing parser code looks fine. With these changes, I was able to get your parser working with test strings "100", ".100", and "100h". You have a few remaining minor bugs in your parse action, here is a working version:
Sorry for the delay, good luck in your parsing endeavors!
- Paul McGuire