Archived
1

Redesign of the Evaluation System

This commit is contained in:
Kim Wittenburg
2014-09-13 23:16:44 +02:00
parent a3e1cc6df4
commit b50c444578
20 changed files with 431 additions and 135 deletions

View File

@@ -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