Redesign of the Evaluation System
This commit is contained in:
@@ -9,6 +9,11 @@
|
||||
#import "MPElementParser.h"
|
||||
#import "NSRegularExpression+MPParsingAdditions.h"
|
||||
|
||||
#import "MPParsedFactor.h"
|
||||
#import "MPParsedNumber.h"
|
||||
#import "MPParsedVariable.h"
|
||||
#import "MPParsedOperator.h"
|
||||
|
||||
#define MPMultiplicationSymbol @"*"
|
||||
|
||||
@interface MPElementParser ()
|
||||
@@ -24,11 +29,8 @@
|
||||
|
||||
- (NSRange)parseWhitespaces;
|
||||
- (NSRange)parseMultiplicationSymbol;
|
||||
- (NSRange)parseOperators;
|
||||
- (NSUInteger)countOperatorsInRange:(NSRange)range
|
||||
multiplicator:(out NSDecimalNumber *__autoreleasing *)multiplicator;
|
||||
- (NSRange)parseNumber;
|
||||
- (NSDecimalNumber *)numberInRange:(NSRange)range;
|
||||
- (MPParsedOperator *)parseOperators;
|
||||
- (MPParsedNumber *)parseNumber;
|
||||
|
||||
@end
|
||||
|
||||
@@ -84,7 +86,7 @@ static BOOL useUserDefaults;
|
||||
|
||||
- (NSArray *)parseElement:(NSString *)string
|
||||
previousProduct:(MPParsedProduct *)previousProduct
|
||||
nextFactor:(MPParsedFactor *)nextFactor
|
||||
nextFactor:(id<MPParsedFactor>)nextFactor
|
||||
error:(out MPParseError *__autoreleasing *)error
|
||||
{
|
||||
return [self parseElement:string
|
||||
@@ -97,7 +99,7 @@ static BOOL useUserDefaults;
|
||||
|
||||
- (NSArray *)parseElement:(NSString *)string
|
||||
previousProduct:(MPParsedProduct *)previousProduct
|
||||
nextFactor:(MPParsedFactor *)nextFactor
|
||||
nextFactor:(id<MPParsedFactor>)nextFactor
|
||||
definesVariable:(BOOL)flag
|
||||
definedVariable:(NSString *__autoreleasing *)variableName
|
||||
error:(out MPParseError *__autoreleasing *)error
|
||||
@@ -123,90 +125,86 @@ static BOOL useUserDefaults;
|
||||
NSMutableArray *products = [[NSMutableArray alloc] init];
|
||||
MPParsedProduct *currentProduct = previousProduct;
|
||||
|
||||
while (![self isAtEnd]) {
|
||||
while (YES) {
|
||||
[self parseWhitespaces];
|
||||
|
||||
NSRange multiplicationSymbolRange = [self parseMultiplicationSymbol];
|
||||
BOOL hasMultiplicationSymbol = multiplicationSymbolRange.location != NSNotFound;
|
||||
|
||||
NSRange operatorsRange = [self parseOperators];
|
||||
BOOL hasOperators = operatorsRange.location != NSNotFound;
|
||||
MPParsedOperator *operators = [self parseOperators];
|
||||
|
||||
// NSRange functionRange = ...
|
||||
// BOOL hasFunction = functionRange.location != NSNotFound;
|
||||
|
||||
NSRange numberRange = [self parseNumber];
|
||||
BOOL hasNumber = numberRange.location != NSNotFound;
|
||||
|
||||
|
||||
NSDecimalNumber *operatorMultiplicator;
|
||||
NSUInteger operatorCount = [self countOperatorsInRange:operatorsRange
|
||||
multiplicator:&operatorMultiplicator];
|
||||
|
||||
if (!hasNumber) {
|
||||
MPParsedNumber *number = [self parseNumber];
|
||||
|
||||
|
||||
if (!number.exists) {
|
||||
if ([self isAtEnd] && nextFactor != nil) {
|
||||
if (hasMultiplicationSymbol) {
|
||||
if (operatorCount > self.maximumOperatorChainLengthInFunction) {
|
||||
self.error = MPParseError(operatorsRange, @"Too many operators in multiplication.");
|
||||
if (operators.numberOfOperators > self.maximumOperatorChainLengthInFunction) {
|
||||
self.error = MPParseError(operators.range, @"Too many operators in multiplication.");
|
||||
return nil;
|
||||
}
|
||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:operatorMultiplicator]];
|
||||
} else if (hasOperators) {
|
||||
if (operatorCount > self.maximumOperatorChainLength) {
|
||||
self.error = MPParseError(operatorsRange, @"Too many operators.");
|
||||
[currentProduct addFactor:operators];
|
||||
} else if (operators.exists) {
|
||||
if (operators.numberOfOperators > self.maximumOperatorChainLength) {
|
||||
self.error = MPParseError(operators.range, @"Too many operators.");
|
||||
return nil;
|
||||
}
|
||||
[products addObject:currentProduct];
|
||||
currentProduct = [[MPParsedProduct alloc] init];
|
||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:[[NSDecimalNumber alloc] initWithUnsignedInteger:operatorCount]]];
|
||||
[currentProduct addFactor:operators];
|
||||
} else if (self.allowsImplicitMultiplications) {
|
||||
NSLog(@"Here I am");
|
||||
if (!currentProduct) {
|
||||
currentProduct = [[MPParsedProduct alloc] init];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"ERR");
|
||||
self.error = MPParseError(NSMakeRange(self.parsePosition, 0), @"Implicit Multiplication not allowed.");
|
||||
return nil;
|
||||
}
|
||||
break;
|
||||
} else if ([self isAtEnd]) {
|
||||
self.error = MPParseError(NSMakeRange(self.parsePosition, 0), @"Unexpected End. Expected Number.");
|
||||
return nil;
|
||||
if (hasMultiplicationSymbol || operators.exists) {
|
||||
self.error = MPParseError(NSMakeRange(self.parsePosition, 0), @"Unexpected End. Expected Number.");
|
||||
return nil;
|
||||
}
|
||||
} else {
|
||||
self.error = MPParseError(NSMakeRange(self.parsePosition, 1), @"Unexpected Symbol. Expected Number.");
|
||||
return nil;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
NSDecimalNumber *number = [self numberInRange:numberRange];
|
||||
NSDecimalNumber *value = [operatorMultiplicator decimalNumberByMultiplyingBy:number];
|
||||
|
||||
if (hasMultiplicationSymbol) {
|
||||
if (currentProduct) {
|
||||
if (operatorCount > self.maximumOperatorChainLengthInMultiplication) {
|
||||
self.error = MPParseError(operatorsRange, @"Too many operators in multiplication.");
|
||||
if (operators.numberOfOperators > self.maximumOperatorChainLengthInMultiplication) {
|
||||
self.error = MPParseError(operators.range, @"Too many operators in multiplication.");
|
||||
return nil;
|
||||
}
|
||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:value]];
|
||||
[currentProduct addFactor:operators];
|
||||
[currentProduct addFactor:number];
|
||||
} else {
|
||||
self.error = MPParseError(multiplicationSymbolRange, @"Unexpected Symbol. Expected Number.");
|
||||
return nil;
|
||||
}
|
||||
} else if (hasOperators) {
|
||||
if (operatorCount > self.maximumOperatorChainLength) {
|
||||
self.error = MPParseError(operatorsRange, @"Too many operators.");
|
||||
} else if (operators.exists) {
|
||||
if (operators.numberOfOperators > self.maximumOperatorChainLength) {
|
||||
self.error = MPParseError(operators.range, @"Too many operators.");
|
||||
return nil;
|
||||
}
|
||||
if (currentProduct) {
|
||||
[products addObject:currentProduct];
|
||||
}
|
||||
currentProduct = [[MPParsedProduct alloc] init];
|
||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:value]];
|
||||
currentProduct = [[MPParsedProduct alloc] initWithFactor:operators];
|
||||
[currentProduct addFactor:number];
|
||||
} else if (!currentProduct) {
|
||||
currentProduct = [[MPParsedProduct alloc] init];
|
||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:value]];
|
||||
currentProduct = [[MPParsedProduct alloc] initWithFactor:number];
|
||||
} else if (self.allowsImplicitMultiplications) {
|
||||
[currentProduct addFactor:[MPParsedFactor factorWithDecimalNumber:value]];
|
||||
[currentProduct addFactor:number];
|
||||
} else {
|
||||
self.error = MPParseError(NSMakeRange(numberRange.location, 0), @"Implicit Multiplication not allowed.");
|
||||
self.error = MPParseError(NSMakeRange(number.range.location, 0), @"Implicit Multiplication not allowed.");
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
@@ -276,7 +274,7 @@ static NSRegularExpression *multiplicationSymbolRegex;
|
||||
}
|
||||
|
||||
static NSRegularExpression *operatorsRegex;
|
||||
- (NSRange)parseOperators
|
||||
- (MPParsedOperator *)parseOperators
|
||||
{
|
||||
if (!operatorsRegex) {
|
||||
operatorsRegex = [NSRegularExpression regularExpressionWithPattern:@"\\A\\s*([+-](?:\\s*[+-])*)\\s*"
|
||||
@@ -285,33 +283,18 @@ static NSRegularExpression *operatorsRegex;
|
||||
}
|
||||
NSTextCheckingResult *match = [operatorsRegex firstMatchInString:self.input
|
||||
fromIndex:self.parsePosition];
|
||||
if (match == nil) {
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
NSRange matchRange;
|
||||
if (!match) {
|
||||
matchRange = NSMakeRange(NSNotFound, 0);
|
||||
} else {
|
||||
self.parsePosition = NSMaxRange(match.range);
|
||||
matchRange = [match rangeAtIndex:1];
|
||||
}
|
||||
self.parsePosition = NSMaxRange(match.range);
|
||||
return [match rangeAtIndex:1];
|
||||
return [[MPParsedOperator alloc] initWithRange:matchRange
|
||||
inString:self.input];
|
||||
}
|
||||
|
||||
- (NSUInteger)countOperatorsInRange:(NSRange)range
|
||||
multiplicator:(out NSDecimalNumber *__autoreleasing *)outMultiplicator
|
||||
{
|
||||
if (range.location == NSNotFound) {
|
||||
*outMultiplicator = [NSDecimalNumber one];
|
||||
return 0;
|
||||
}
|
||||
NSString *operatorsString = [self.input substringWithRange:range];
|
||||
NSString *operators = [[operatorsString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:@""];
|
||||
NSInteger multiplicator = 1;
|
||||
for (NSUInteger characterIndex; characterIndex < operators.length; characterIndex++) {
|
||||
if ([[operators substringWithRange:NSMakeRange(characterIndex, 1)] isEqualToString:@"-"]) {
|
||||
multiplicator *= -1;
|
||||
}
|
||||
}
|
||||
*outMultiplicator = [[NSDecimalNumber alloc] initWithInteger:multiplicator];
|
||||
return operators.length;
|
||||
}
|
||||
|
||||
- (NSRange)parseNumber
|
||||
- (MPParsedNumber *)parseNumber
|
||||
{
|
||||
NSString *decimalSeparatorRegexString = [NSRegularExpression escapedPatternForString:[[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]];
|
||||
NSString *numberRegexFormat = [NSString stringWithFormat:@"\\A\\s*((?:\\d+(?:%@\\d+)?)|(?:%@\\d+))\\s*", decimalSeparatorRegexString, decimalSeparatorRegexString];
|
||||
@@ -320,17 +303,15 @@ static NSRegularExpression *operatorsRegex;
|
||||
error:NULL];
|
||||
NSTextCheckingResult *match = [numberRegex firstMatchInString:self.input
|
||||
fromIndex:self.parsePosition];
|
||||
NSRange matchRange;
|
||||
if (!match) {
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
matchRange = NSMakeRange(NSNotFound, 0);
|
||||
} else {
|
||||
self.parsePosition = NSMaxRange(match.range);
|
||||
matchRange = [match rangeAtIndex:1];
|
||||
}
|
||||
self.parsePosition = NSMaxRange(match.range);
|
||||
return [match rangeAtIndex:1];
|
||||
}
|
||||
|
||||
- (NSDecimalNumber *)numberInRange:(NSRange)range
|
||||
{
|
||||
NSString *numberString = [self.input substringWithRange:range];
|
||||
return [NSDecimalNumber decimalNumberWithString:numberString];
|
||||
return [[MPParsedNumber alloc] initWithRange:matchRange
|
||||
inString:self.input];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user