Skip to content
Browse files

strong support for implicit multiplication when the logical not opera…

…tor is involved
  • Loading branch information...
1 parent d903be9 commit 054476ed54c8ea6df7299e1c076f57bd1f45cbab @davedelong committed
View
1 DDMathParser/DDMathStringToken.h
@@ -25,6 +25,7 @@
@property (nonatomic,readonly) DDTokenType tokenType;
@property (nonatomic,readonly) DDOperator operatorType;
@property (nonatomic,readonly) DDOperatorArity operatorArity;
+@property (nonatomic,readonly) DDOperatorAssociativity operatorAssociativity;
@property (nonatomic,readonly) NSInteger operatorPrecedence;
@property (nonatomic,readonly) NSString *operatorFunction;
View
5 DDMathParser/DDMathStringToken.m
@@ -95,6 +95,11 @@ - (NSString *)operatorFunction {
return [operatorInfo function];
}
+- (DDOperatorAssociativity)operatorAssociativity {
+ if (ambiguous) { return 0; }
+ return [operatorInfo defaultAssociativity];
+}
+
- (void)resolveToOperator:(DDOperator)operator {
DD_RELEASE(operatorInfo);
operatorInfo = nil;
View
21 DDMathParser/DDMathStringTokenizer.m
@@ -188,7 +188,7 @@ - (BOOL)_processUnknownOperatorToken:(DDMathStringToken *)token withError:(NSErr
}
}
- if (token == nil && [[previousToken token] isEqual:@"!"]) {
+ if ([[previousToken token] isEqual:@"!"] && [previousToken operatorType] == DDOperatorInvalid) {
[previousToken resolveToOperator:DDOperatorFactorial];
if (error != nil) {
*error = nil;
@@ -237,18 +237,31 @@ - (BOOL)_processImplicitMultiplicationWithToken:(DDMathStringToken *)token error
**/
DDMathStringToken *previousToken = [_tokens lastObject];
if (previousToken != nil && token != nil) {
+ BOOL shouldInsertMultiplier = NO;
if ([previousToken tokenType] == DDTokenTypeNumber ||
[previousToken tokenType] == DDTokenTypeVariable ||
[previousToken operatorType] == DDOperatorParenthesisClose) {
if ([token tokenType] != DDTokenTypeOperator || [token operatorType] == DDOperatorParenthesisOpen) {
//inject a "multiplication" token:
- DDMathStringToken * multiply = [DDMathStringToken mathStringTokenWithToken:@"*" type:DDTokenTypeOperator];
-
- [self appendToken:multiply];
+ shouldInsertMultiplier = YES;
}
}
+
+ if (shouldInsertMultiplier == NO && [previousToken tokenType] == DDTokenTypeOperator && [token tokenType] == DDTokenTypeOperator) {
+ if ([previousToken operatorArity] == DDOperatorArityUnary && [token operatorArity] == DDOperatorArityUnary) {
+ if ([previousToken operatorAssociativity] != [token operatorAssociativity]) {
+ shouldInsertMultiplier = YES;
+ }
+ }
+ }
+
+ if (shouldInsertMultiplier) {
+ DDMathStringToken * multiply = [DDMathStringToken mathStringTokenWithToken:@"*" type:DDTokenTypeOperator];
+
+ [self appendToken:multiply];
+ }
}
return YES;
}
View
2 DDMathParser/_DDOperatorInfo.h
@@ -13,10 +13,12 @@
@property (nonatomic, readonly) DDOperator operator;
@property (nonatomic, readonly) DDOperatorArity arity;
+@property (nonatomic, assign) DDOperatorAssociativity defaultAssociativity;
@property (nonatomic, readonly) NSInteger precedence;
@property (nonatomic, readonly, DD_STRONG) NSString *token;
@property (nonatomic, readonly, DD_STRONG) NSString *function;
+ (NSArray *)allOperators;
++ (NSArray *)infosForOperator:(DDOperator)operator;
@end
View
76 DDMathParser/_DDOperatorInfo.m
@@ -12,15 +12,17 @@ @implementation _DDOperatorInfo
@synthesize operator=_operator;
@synthesize arity=_arity;
+@synthesize defaultAssociativity=_defaultAssociativity;
@synthesize precedence=_precedence;
@synthesize token=_token;
@synthesize function=_function;
-- (id)initWithOperator:(DDOperator)operator arity:(DDOperatorArity)arity precedence:(NSInteger)precedence token:(NSString *)token function:(NSString *)function {
+- (id)initWithOperator:(DDOperator)operator arity:(DDOperatorArity)arity precedence:(NSInteger)precedence token:(NSString *)token function:(NSString *)function associativity:(DDOperatorAssociativity)associativity {
self = [super init];
if (self) {
_operator = operator;
_arity = arity;
+ _defaultAssociativity = associativity;
_precedence = precedence;
_token = DD_RETAIN(token);
_function = DD_RETAIN(function);
@@ -28,8 +30,12 @@ - (id)initWithOperator:(DDOperator)operator arity:(DDOperatorArity)arity precede
return self;
}
-+ (id)infoForOperator:(DDOperator)operator arity:(DDOperatorArity)arity precedence:(NSInteger)precedence token:(NSString *)token function:(NSString *)function {
- return DD_AUTORELEASE([[self alloc] initWithOperator:operator arity:arity precedence:precedence token:token function:function]);
++ (id)infoForOperator:(DDOperator)operator arity:(DDOperatorArity)arity precedence:(NSInteger)precedence token:(NSString *)token function:(NSString *)function associativity:(DDOperatorAssociativity)associativity {
+ return DD_AUTORELEASE([[self alloc] initWithOperator:operator arity:arity precedence:precedence token:token function:function associativity:associativity]);
+}
+
++ (NSArray *)infosForOperator:(DDOperator)operator {
+ return [[self allOperators] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"operator = %d", operator]];
}
#if !DD_HAS_ARC
@@ -44,86 +50,86 @@ + (NSArray *)_buildOperators {
NSMutableArray *operators = [NSMutableArray array];
NSInteger precedence = 0;
- [operators addObject:[self infoForOperator:DDOperatorLogicalOr arity:DDOperatorArityBinary precedence:precedence token:@"||" function:@"l_or"]];
- [operators addObject:[self infoForOperator:DDOperatorLogicalOr arity:DDOperatorArityBinary precedence:precedence token:@"\u2228" function:@"l_or"]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalOr arity:DDOperatorArityBinary precedence:precedence token:@"||" function:@"l_or" associativity:DDOperatorAssociativityLeft]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalOr arity:DDOperatorArityBinary precedence:precedence token:@"\u2228" function:@"l_or" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorLogicalAnd arity:DDOperatorArityBinary precedence:precedence token:@"&&" function:@"l_and"]];
- [operators addObject:[self infoForOperator:DDOperatorLogicalAnd arity:DDOperatorArityBinary precedence:precedence token:@"\u2227" function:@"l_and"]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalAnd arity:DDOperatorArityBinary precedence:precedence token:@"&&" function:@"l_and" associativity:DDOperatorAssociativityLeft]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalAnd arity:DDOperatorArityBinary precedence:precedence token:@"\u2227" function:@"l_and" associativity:DDOperatorAssociativityLeft]];
precedence++;
// == and != have the same precedence
- [operators addObject:[self infoForOperator:DDOperatorLogicalEqual arity:DDOperatorArityBinary precedence:precedence token:@"==" function:@"l_eq"]];
- [operators addObject:[self infoForOperator:DDOperatorLogicalNotEqual arity:DDOperatorArityBinary precedence:precedence token:@"!=" function:@"l_neq"]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalEqual arity:DDOperatorArityBinary precedence:precedence token:@"==" function:@"l_eq" associativity:DDOperatorAssociativityLeft]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalNotEqual arity:DDOperatorArityBinary precedence:precedence token:@"!=" function:@"l_neq" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorLogicalLessThan arity:DDOperatorArityBinary precedence:precedence token:@"<" function:@"l_lt"]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalLessThan arity:DDOperatorArityBinary precedence:precedence token:@"<" function:@"l_lt" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorLogicalGreaterThan arity:DDOperatorArityBinary precedence:precedence token:@">" function:@"l_gt"]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalGreaterThan arity:DDOperatorArityBinary precedence:precedence token:@">" function:@"l_gt" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorLogicalLessThanOrEqual arity:DDOperatorArityBinary precedence:precedence token:@"<=" function:@"l_ltoe"]];
- [operators addObject:[self infoForOperator:DDOperatorLogicalLessThanOrEqual arity:DDOperatorArityBinary precedence:precedence token:@"\u2264" function:@"l_ltoe"]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalLessThanOrEqual arity:DDOperatorArityBinary precedence:precedence token:@"<=" function:@"l_ltoe" associativity:DDOperatorAssociativityLeft]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalLessThanOrEqual arity:DDOperatorArityBinary precedence:precedence token:@"\u2264" function:@"l_ltoe" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorLogicalGreaterThanOrEqual arity:DDOperatorArityBinary precedence:precedence token:@">=" function:@"l_gtoe"]];
- [operators addObject:[self infoForOperator:DDOperatorLogicalGreaterThanOrEqual arity:DDOperatorArityBinary precedence:precedence token:@"\u2265" function:@"l_gtoe"]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalGreaterThanOrEqual arity:DDOperatorArityBinary precedence:precedence token:@">=" function:@"l_gtoe" associativity:DDOperatorAssociativityLeft]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalGreaterThanOrEqual arity:DDOperatorArityBinary precedence:precedence token:@"\u2265" function:@"l_gtoe" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorLogicalNot arity:DDOperatorArityUnary precedence:precedence token:@"!" function:@"l_not"]];
- [operators addObject:[self infoForOperator:DDOperatorLogicalNot arity:DDOperatorArityUnary precedence:precedence token:@"\u00ac" function:@"l_not"]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalNot arity:DDOperatorArityUnary precedence:precedence token:@"!" function:@"l_not" associativity:DDOperatorAssociativityRight]];
+ [operators addObject:[self infoForOperator:DDOperatorLogicalNot arity:DDOperatorArityUnary precedence:precedence token:@"\u00ac" function:@"l_not" associativity:DDOperatorAssociativityRight]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorBitwiseOr arity:DDOperatorArityBinary precedence:precedence token:@"|" function:@"or"]];
+ [operators addObject:[self infoForOperator:DDOperatorBitwiseOr arity:DDOperatorArityBinary precedence:precedence token:@"|" function:@"or" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorBitwiseXor arity:DDOperatorArityBinary precedence:precedence token:@"^" function:@"xor"]];
+ [operators addObject:[self infoForOperator:DDOperatorBitwiseXor arity:DDOperatorArityBinary precedence:precedence token:@"^" function:@"xor" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorBitwiseAnd arity:DDOperatorArityBinary precedence:precedence token:@"&" function:@"and"]];
+ [operators addObject:[self infoForOperator:DDOperatorBitwiseAnd arity:DDOperatorArityBinary precedence:precedence token:@"&" function:@"and" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorLeftShift arity:DDOperatorArityBinary precedence:precedence token:@"<<" function:@"lshift"]];
+ [operators addObject:[self infoForOperator:DDOperatorLeftShift arity:DDOperatorArityBinary precedence:precedence token:@"<<" function:@"lshift" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorRightShift arity:DDOperatorArityBinary precedence:precedence token:@">>" function:@"rshift"]];
+ [operators addObject:[self infoForOperator:DDOperatorRightShift arity:DDOperatorArityBinary precedence:precedence token:@">>" function:@"rshift" associativity:DDOperatorAssociativityLeft]];
precedence++;
// addition and subtraction have the same precedence
- [operators addObject:[self infoForOperator:DDOperatorAdd arity:DDOperatorArityBinary precedence:precedence token:@"+" function:@"add"]];
- [operators addObject:[self infoForOperator:DDOperatorMinus arity:DDOperatorArityBinary precedence:precedence token:@"-" function:@"subtract"]];
+ [operators addObject:[self infoForOperator:DDOperatorAdd arity:DDOperatorArityBinary precedence:precedence token:@"+" function:@"add" associativity:DDOperatorAssociativityLeft]];
+ [operators addObject:[self infoForOperator:DDOperatorMinus arity:DDOperatorArityBinary precedence:precedence token:@"-" function:@"subtract" associativity:DDOperatorAssociativityLeft]];
precedence++;
// multiplication and division have the same precedence
- [operators addObject:[self infoForOperator:DDOperatorMultiply arity:DDOperatorArityBinary precedence:precedence token:@"*" function:@"multiply"]];
- [operators addObject:[self infoForOperator:DDOperatorDivide arity:DDOperatorArityBinary precedence:precedence token:@"/" function:@"divide"]];
+ [operators addObject:[self infoForOperator:DDOperatorMultiply arity:DDOperatorArityBinary precedence:precedence token:@"*" function:@"multiply" associativity:DDOperatorAssociativityLeft]];
+ [operators addObject:[self infoForOperator:DDOperatorDivide arity:DDOperatorArityBinary precedence:precedence token:@"/" function:@"divide" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorModulo arity:DDOperatorArityBinary precedence:precedence token:@"%" function:@"mod"]];
+ [operators addObject:[self infoForOperator:DDOperatorModulo arity:DDOperatorArityBinary precedence:precedence token:@"%" function:@"mod" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorBitwiseNot arity:DDOperatorArityUnary precedence:precedence token:@"~" function:@"not"]];
+ [operators addObject:[self infoForOperator:DDOperatorBitwiseNot arity:DDOperatorArityUnary precedence:precedence token:@"~" function:@"not" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorUnaryMinus arity:DDOperatorArityUnary precedence:precedence token:@"-" function:@"negate"]];
+ [operators addObject:[self infoForOperator:DDOperatorUnaryMinus arity:DDOperatorArityUnary precedence:precedence token:@"-" function:@"negate" associativity:DDOperatorAssociativityRight]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorUnaryPlus arity:DDOperatorArityUnary precedence:precedence token:@"+" function:@""]];
+ [operators addObject:[self infoForOperator:DDOperatorUnaryPlus arity:DDOperatorArityUnary precedence:precedence token:@"+" function:@"" associativity:DDOperatorAssociativityRight]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorFactorial arity:DDOperatorArityUnary precedence:precedence token:@"!" function:@"factorial"]];
+ [operators addObject:[self infoForOperator:DDOperatorFactorial arity:DDOperatorArityUnary precedence:precedence token:@"!" function:@"factorial" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorPower arity:DDOperatorArityBinary precedence:precedence token:@"**" function:@"pow"]];
+ [operators addObject:[self infoForOperator:DDOperatorPower arity:DDOperatorArityBinary precedence:precedence token:@"**" function:@"pow" associativity:DDOperatorAssociativityRight]];
precedence++;
// ( and ) have the same precedence
- [operators addObject:[self infoForOperator:DDOperatorParenthesisOpen arity:DDOperatorArityUnknown precedence:precedence token:@"(" function:@""]];
- [operators addObject:[self infoForOperator:DDOperatorParenthesisClose arity:DDOperatorArityUnknown precedence:precedence token:@")" function:@""]];
+ [operators addObject:[self infoForOperator:DDOperatorParenthesisOpen arity:DDOperatorArityUnknown precedence:precedence token:@"(" function:@"" associativity:DDOperatorAssociativityLeft]];
+ [operators addObject:[self infoForOperator:DDOperatorParenthesisClose arity:DDOperatorArityUnknown precedence:precedence token:@")" function:@"" associativity:DDOperatorAssociativityLeft]];
precedence++;
- [operators addObject:[self infoForOperator:DDOperatorComma arity:DDOperatorArityUnknown precedence:precedence token:@"," function:@""]];
+ [operators addObject:[self infoForOperator:DDOperatorComma arity:DDOperatorArityUnknown precedence:precedence token:@"," function:@"" associativity:DDOperatorAssociativityLeft]];
precedence++;
return operators;

0 comments on commit 054476e

Please sign in to comment.
Something went wrong with that request. Please try again.