From af5a200a68ed12efec4b29b57fa22c632aaf91fa Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Thu, 19 Jun 2008 19:01:31 +0200 Subject: Fix number parsing. --- MLKDoubleFloat.m | 19 +++++++++++++++++++ MLKDynamicContext.m | 13 +++++++++++++ MLKRatio.m | 5 +++-- MLKReader.m | 25 +++++++++++++++++++++++-- MLKReadtable.m | 11 ++++------- MLKSingleFloat.m | 14 ++++++++++++++ 6 files changed, 76 insertions(+), 11 deletions(-) diff --git a/MLKDoubleFloat.m b/MLKDoubleFloat.m index 98daa09..e3cb94d 100644 --- a/MLKDoubleFloat.m +++ b/MLKDoubleFloat.m @@ -16,12 +16,16 @@ * along with this program. If not, see . */ +#define _XOPEN_SOURCE 600 // strtof (not actually needed here) + #import "MLKSingleFloat.h" #import "MLKDoubleFloat.h" #import #include +#include +#include @implementation MLKDoubleFloat @@ -32,6 +36,13 @@ exponentNegative:(BOOL)exponentNegative { self = [super init]; + char *locale; + + // FIXME: This is probably not thread-safe. + locale = setlocale (LC_NUMERIC, NULL); + setlocale (LC_NUMERIC, "C"); + + // strtod or sscanf -- is there a difference? sscanf ([[NSString stringWithFormat:@"%c%@.%@e%c%@", (negative ? '-' : '+'), intPart, @@ -41,6 +52,9 @@ UTF8String], "%lf", &value); + + setlocale (LC_NUMERIC, locale); + return self; } @@ -117,4 +131,9 @@ return [NSString stringWithFormat:@"%@d0",str]; } + +-(NSString *) descriptionForLisp +{ + return [self description]; +} @end diff --git a/MLKDynamicContext.m b/MLKDynamicContext.m index 74c75d0..6bfd03a 100644 --- a/MLKDynamicContext.m +++ b/MLKDynamicContext.m @@ -105,9 +105,11 @@ static MLKDynamicContext *global_context; [readtable setSyntaxType:CONSTITUENT forCharacter:'+']; [readtable setConstituentTrait:PLUS_SIGN forCharacter:'+']; + [readtable setConstituentTrait:SIGN forCharacter:'+']; [readtable setSyntaxType:CONSTITUENT forCharacter:'-']; [readtable setConstituentTrait:MINUS_SIGN forCharacter:'-']; + [readtable setConstituentTrait:SIGN forCharacter:'-']; [readtable setSyntaxType:CONSTITUENT forCharacter:'.']; [readtable setConstituentTrait:DOT forCharacter:'.']; @@ -129,6 +131,17 @@ static MLKDynamicContext *global_context; [readtable setConstituentTrait:EXPONENT_MARKER forCharacter:'F']; [readtable setConstituentTrait:EXPONENT_MARKER forCharacter:'L']; [readtable setConstituentTrait:EXPONENT_MARKER forCharacter:'S']; + + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'d']; + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'e']; + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'f']; + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'l']; + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'s']; + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'D']; + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'E']; + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'F']; + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'L']; + [readtable setConstituentTrait:NUMBER_MARKER forCharacter:'S']; [readtable setSyntaxType:MULTI_ESCAPE forCharacter:'|']; diff --git a/MLKRatio.m b/MLKRatio.m index 3685f1c..476af42 100644 --- a/MLKRatio.m +++ b/MLKRatio.m @@ -41,6 +41,7 @@ self = [super init]; mpq_init (value); mpq_set_str (value, [string UTF8String], 10); + mpq_canonicalize (value); return self; } @@ -49,8 +50,8 @@ negative:(BOOL)negative base:(unsigned int)base { - return [self initWithString:[NSString stringWithFormat:@"%c%@/%@", - (negative ? '-' : '+'), + return [self initWithString:[NSString stringWithFormat:@"%s%@/%@", + (negative ? "-" : ""), numerString, denomString] base:base]; diff --git a/MLKReader.m b/MLKReader.m index 05ee0f0..422fd8f 100644 --- a/MLKReader.m +++ b/MLKReader.m @@ -238,7 +238,7 @@ firstNum = 0; } - negative = (firstNum > 0 && sign == '-'); + negative = (firstNum > 0 && [readtable isMinusSign:sign]); while ((i < [token length]) && [readtable isDecimalDigit:[token characterAtIndex:i]]) @@ -246,6 +246,7 @@ if (i == [token length]) { + //NSLog (@"..."); return [MLKInteger integerWithString: [token substringWithRange: NSMakeRange (firstNum, [token length] - firstNum)] @@ -264,6 +265,7 @@ if (i == [token length] && [readtable isDecimalPoint:firstSeparator]) { + //NSLog (@"+++"); return [MLKInteger integerWithString: [token substringWithRange: NSMakeRange (firstNum, [token length] - firstNum - 1)] @@ -291,6 +293,10 @@ && [readtable isDecimalDigit:[token characterAtIndex:i]]) i++; + //NSLog (@"...2"); + //NSLog (@"%@, %@", + // [token substringWithRange:NSMakeRange (firstNum, exponentMarkerPos - firstNum - 1)], + // [token substringFromIndex:exponent]); return [MLKFloat floatWithExponentMarker:firstSeparator integerPart:[token substringWithRange:NSMakeRange(firstNum, exponentMarkerPos - firstNum - 1)] negative:negative @@ -306,6 +312,10 @@ if (i == [token length]) { + //NSLog (@"...3"); + //NSLog (@"%@, %@", + // [token substringWithRange:NSMakeRange (firstNum, secondNum - firstNum - 1)], + // [token substringFromIndex:secondNum]); return [MLKFloat floatWithExponentMarker:firstSeparator integerPart:[token substringWithRange:NSMakeRange (firstNum, secondNum - firstNum - 1)] negative:negative @@ -333,6 +343,11 @@ && [readtable isDecimalDigit:[token characterAtIndex:i]]) i++; + //NSLog (@"...4"); + //NSLog (@"%@, %@, %@", + // [token substringWithRange:NSMakeRange (firstNum, secondNum - firstNum - 1)], + // [token substringWithRange:NSMakeRange (secondNum, exponentMarkerPos - secondNum)], + // [token substringFromIndex:exponent]); return [MLKFloat floatWithExponentMarker:exponentMarker integerPart:[token substringWithRange:NSMakeRange (firstNum, secondNum - firstNum - 1)] negative:negative @@ -345,11 +360,12 @@ digits: i = firstNum; while ((i < [token length]) - && [readtable isDigit:[token characterAtIndex:0] inBase:base]) + && [readtable isDigit:[token characterAtIndex:i] inBase:base]) i++; if (i == [token length]) { + //NSLog (@"###"); return [MLKInteger integerWithString: [token substringWithRange: NSMakeRange (firstNum, [token length] - firstNum)] @@ -361,6 +377,11 @@ i++; secondNum = i; + //NSLog (@"RRR"); + //NSLog (@"n: %@", [token substringWithRange: + // NSMakeRange (firstNum, + // secondNum - firstNum - 1)]); + //NSLog (@"d: %@", [token substringFromIndex:secondNum]); return [MLKRatio ratioWithNumeratorString: [token substringWithRange: NSMakeRange (firstNum, diff --git a/MLKReadtable.m b/MLKReadtable.m index 8d56d72..393c4d1 100644 --- a/MLKReadtable.m +++ b/MLKReadtable.m @@ -132,11 +132,8 @@ DEFINE_SYNTAX_PREDICATE(isConstituentCharacter:, CONSTITUENT) -(BOOL) character:(unichar)ch hasTrait:(enum MLKConstituentTrait)trait { - NSNumber *traits = [_traits objectForKey:[NSNumber numberWithLong:ch]]; - if (!traits) - return (trait == ALPHABETIC); - else - return [traits intValue] & trait; + int traits = [self characterConstituentTraits:ch]; + return (traits & trait) != 0; } @@ -193,9 +190,9 @@ DEFINE_TRAIT_PREDICATE(isDot:, DOT) -(BOOL) isDigit:(unichar)ch inBase:(int)base { if (base < 11) - return (ch < '0' + base); + return ('0' <= ch && ch < '0' + base); else - return (ch <= '9' + return (('0' <= ch && ch <= '9') || ('A' <= ch && ch < 'A' + base - 10) || ('a' <= ch && ch < 'a' + base - 10)); } diff --git a/MLKSingleFloat.m b/MLKSingleFloat.m index 76965ec..85cc934 100644 --- a/MLKSingleFloat.m +++ b/MLKSingleFloat.m @@ -16,12 +16,16 @@ * along with this program. If not, see . */ +#define _XOPEN_SOURCE 600 // strtof + #import "MLKSingleFloat.h" #import "MLKDoubleFloat.h" #import #include +#include +#include @implementation MLKSingleFloat @@ -32,6 +36,13 @@ exponentNegative:(BOOL)exponentNegative { self = [super init]; + char *locale; + + // FIXME: This is probably not thread-safe. + locale = setlocale (LC_NUMERIC, NULL); + setlocale (LC_NUMERIC, "C"); + + // strtof or sscanf -- is there a difference? sscanf ([[NSString stringWithFormat:@"%c%@.%@e%c%@", (negative ? '-' : '+'), intPart, @@ -41,6 +52,9 @@ UTF8String], "%f", &value); + + setlocale (LC_NUMERIC, locale); + return self; } -- cgit v1.2.3