Skip to content
Browse files

Moved parsing files to common subfolder, added readme and license

  • Loading branch information...
1 parent 8d37c19 commit 47bf70adce7cbd1ac0b4077681c1c64bee1d6e02 @davedelong committed Nov 20, 2010
View
1 .gitignore
@@ -2,3 +2,4 @@ build
**/*.pbxuser
**/*.perspective*
**/*.mode*
+.DS_Store
View
6 DDMathParser.xcodeproj/project.pbxproj
@@ -54,6 +54,7 @@
5554D58912944AFD00A62529 /* DDMathEvaluator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDMathEvaluator.h; sourceTree = "<group>"; };
5554D58A12944AFD00A62529 /* DDMathEvaluator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDMathEvaluator.m; sourceTree = "<group>"; };
5554D5EF129478E800A62529 /* DDMathEvaluator+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DDMathEvaluator+Private.h"; sourceTree = "<group>"; };
+ 55BA673E1298ECA2002279A5 /* DDMathParsing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DDMathParsing.h; path = DDMathParser/DDMathParsing.h; sourceTree = "<group>"; };
55BFA9A6128CDDEB00A80228 /* UnitTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
55BFA9A7128CDDEB00A80228 /* UnitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "UnitTests-Info.plist"; sourceTree = "<group>"; };
55BFA9AE128CDE7600A80228 /* ParserTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserTests.h; sourceTree = "<group>"; };
@@ -70,7 +71,6 @@
55F795F11293235A00EF2716 /* TokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TokenizerTests.m; sourceTree = "<group>"; };
55F7963512934A1400EF2716 /* DDExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDExpression.h; sourceTree = "<group>"; };
55F7963612934A1400EF2716 /* DDExpression.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDExpression.m; sourceTree = "<group>"; };
- 55F7969C129383B900EF2716 /* MathGrammar.grammar */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MathGrammar.grammar; sourceTree = "<group>"; };
55F9EFE51295A99700F4A9FD /* DDMathFunctionContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDMathFunctionContainer.h; sourceTree = "<group>"; };
55F9EFE61295A99700F4A9FD /* DDMathFunctionContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDMathFunctionContainer.m; sourceTree = "<group>"; };
55F9EFE81295A9AB00F4A9FD /* DDTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDTypes.h; sourceTree = "<group>"; };
@@ -122,6 +122,7 @@
children = (
32A70AAB03705E1F00C91783 /* DDMathParser_Prefix.pch */,
08FB7796FE84155DC02AAC07 /* main.m */,
+ 55BA673E1298ECA2002279A5 /* DDMathParsing.h */,
55BFA9B2128CDEA200A80228 /* Parser */,
55F7966612934F8900EF2716 /* Evaluator */,
55BFA9BA128CDF8F00A80228 /* Unit Tests */,
@@ -155,9 +156,9 @@
55BFA9BE128CDFD600A80228 /* DDMathStringTokenizer.m */,
55F795E11293175B00EF2716 /* DDMathStringToken.h */,
55F795E21293175B00EF2716 /* DDMathStringToken.m */,
- 55F7969C129383B900EF2716 /* MathGrammar.grammar */,
);
name = Parser;
+ path = DDMathParser;
sourceTree = "<group>";
};
55BFA9BA128CDF8F00A80228 /* Unit Tests */ = {
@@ -194,6 +195,7 @@
55F9EFF01295AFB500F4A9FD /* _DDVariableExpression.m */,
);
name = Evaluator;
+ path = DDMathParser;
sourceTree = "<group>";
};
C6859EA2029092E104C91782 /* Documentation */ = {
View
0 DDExpression.h → DDMathParser/DDExpression.h
File renamed without changes.
View
0 DDExpression.m → DDMathParser/DDExpression.m
File renamed without changes.
View
0 DDMathEvaluator+Private.h → DDMathParser/DDMathEvaluator+Private.h
File renamed without changes.
View
0 DDMathEvaluator.h → DDMathParser/DDMathEvaluator.h
File renamed without changes.
View
0 DDMathEvaluator.m → DDMathParser/DDMathEvaluator.m
File renamed without changes.
View
0 DDMathFunctionContainer.h → DDMathParser/DDMathFunctionContainer.h
File renamed without changes.
View
0 DDMathFunctionContainer.m → DDMathParser/DDMathFunctionContainer.m
File renamed without changes.
View
0 DDMathParser.h → DDMathParser/DDMathParser.h
File renamed without changes.
View
5 DDMathParser.m → DDMathParser/DDMathParser.m
@@ -94,7 +94,10 @@ - (void) dealloc {
- (DDMathStringToken *) currentToken {
if (currentTokenIndex >= [[tokenizer tokens] count]) { return nil; }
- return [[tokenizer tokens] objectAtIndex:currentTokenIndex];
+ if (currentTokenIndex == 0) {
+ return [[tokenizer tokens] objectAtIndex:currentTokenIndex];
+ }
+ return [[tokenizer tokens] objectAtIndex:currentTokenIndex-1];
}
- (DDMathStringToken *) nextToken {
View
12 DDMathParser/DDMathParsing.h
@@ -0,0 +1,12 @@
+//
+// DDMathParsing.h
+// DDMathParser
+//
+// Created by Dave DeLong on 11/20/10.
+// Copyright 2010 Home. All rights reserved.
+//
+
+#import "DDMathEvaluator.h"
+#import "DDExpression.h"
+#import "DDMathParser.h"
+#import "DDTypes.h"
View
0 DDMathStringToken.h → DDMathParser/DDMathStringToken.h
File renamed without changes.
View
0 DDMathStringToken.m → DDMathParser/DDMathStringToken.m
File renamed without changes.
View
0 DDMathStringTokenizer.h → DDMathParser/DDMathStringTokenizer.h
File renamed without changes.
View
0 DDMathStringTokenizer.m → DDMathParser/DDMathStringTokenizer.m
File renamed without changes.
View
0 DDTypes.h → DDMathParser/DDTypes.h
File renamed without changes.
View
0 _DDFunctionExpression.h → DDMathParser/_DDFunctionExpression.h
File renamed without changes.
View
0 _DDFunctionExpression.m → DDMathParser/_DDFunctionExpression.m
File renamed without changes.
View
0 _DDNumberExpression.h → DDMathParser/_DDNumberExpression.h
File renamed without changes.
View
0 _DDNumberExpression.m → DDMathParser/_DDNumberExpression.m
File renamed without changes.
View
0 _DDVariableExpression.h → DDMathParser/_DDVariableExpression.h
File renamed without changes.
View
0 _DDVariableExpression.m → DDMathParser/_DDVariableExpression.m
File renamed without changes.
View
78 README.markdown
@@ -0,0 +1,78 @@
+# DDMathParser
+
+You have an `NSString`. You want an `NSNumber`. Previously, you would have to rely on [abusing `NSPredicate`](http://tumblr.com/xqopow93r) to turn your string into an `NSExpression` that you could then evaluate. However, this has a major flaw: extending it to support functions that aren't built-in to `NSExpression` provided for some awkward syntax. So if you really need `sin()`, you have to jump through some intricate hoops to get it.
+
+You could also have used [`GCMathParser`](http://apptree.net/parser.htm). This, however, isn't extensible at all. So if you really needed a `floor()` function, you're out of luck.
+
+Thus, `DDMathParser`. It is written to be identical to `NSExpression` in all the ways that matter (in fact, it actually uses `NSExpression` to evaluate many of its built-in functions), but with the major addition that you can define new functions as you need.
+
+### Registering Functions
+
+Registering new functions is easy. You just need a block, a name, and the number of arguments the function accepts. So for example:
+
+ DDMathFunction function = ^ DDExpression* (NSArray * args, NSDictionary * variables, DDMathEvaluator * evaluator) {
+ NSNumber * n = [[args objectAtIndex:0] evaluateWithSubstitutions:variables evaluator:evaluator];
+ NSNumber * result = [NSNumber numberWithDouble:[n doubleValue] * 42.0f];
+ return [DDExpression numberExpressionWithNumber:result];
+ };
+ [[DDMathEvaluator sharedMathEvaluator] registerFunction:function forName:@"multiplyBy42" numberOfArguments:1];
+
+ NSLog(@"%@", [[DDMathEvaluator sharedMathEvaluator] evaluateString:@"multiplyBy42(3)" withSubstitutions:nil]); //logs "126"
+
+You can also unregister added functions. You cannot unregister built-in functions, nor can they be overridden.
+
+Function names must begin with a letter, and can contain letters and digits. Functions are case-insensitive. (`mUlTiPlYbY42` is the same as `multiplyby42`)
+
+### Variables
+
+If you don't know what the value of a particular term should be when the string is constructed, that's ok; simply use a variable:
+
+ NSString * math = @"6 * $a";
+
+Then when you figure out what the value is supposed to be, you can pass it along in the substitution dictionary:
+
+ NSLog(@"%@", [[DDMathEvaluator sharedMathEvaluator] evaluateString:math withSubstitutions:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:7] forKey:@"a"]]); //logs "42"
+
+Variables are denoted in the source string as beginning with `$` and can contain numbers or letters. They are case sensitive. (`$a` is not the same as `$A`)
+
+### Associativity
+
+By default, all binary operators are left associative. That means if you give a string, such as `@"2 ** 3 ** 2"`, it will be parsed as `@"(2 ** 3) ** 2`, in order to maintain parity with `NSExpression`.
+
+If you want this operator to be parsed with right associativity, you can do so like this:
+
+ DDMathParser * parser = [DDMathParser mathParserWithString:@"2 ** 3 ** 2"];
+ [parser setPowerAssociativity:DDMathParserAssociativityRight];
+ DDExpression * e = [parser parsedExpression];
+
+All binary operators can have their associativity changed this way.
+
+## Usage
+
+Simply copy the "DDMathParser" subfolder into your project, `#import "DDMathParsing.h"`, and you're good to go.
+
+## Compatibility
+
+`DDMathParser` requires blocks, so therefore is only compatible with iOS 4+ and Mac OS X 10.6+.
+
+## License
+
+Copyright (c) 2010 Dave DeLong
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

0 comments on commit 47bf70a

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