Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added support for encoding and decoding parsers, meaning you no longe…

…r have to construct the parser from scratch each run.
  • Loading branch information...
commit c0f37abcac3e0dcc229d6450d787ff8437e4916c 1 parent b8e7060
@beelsebob beelsebob authored
View
2  CoreParse/Grammar/CPGrammar.h
@@ -14,7 +14,7 @@
/**
* The CPGrammar class represents a context free grammar. Grammars can be used later to construct parsers.
*/
-@interface CPGrammar : NSObject
+@interface CPGrammar : NSObject <NSCoding>
///---------------------------------------------------------------------------------------
/// @name Creating and Initialising a Grammar
View
23 CoreParse/Grammar/CPGrammar.m
@@ -257,9 +257,32 @@ - (id)init
return [self initWithStart:nil rules:[NSArray array]];
}
+#define CPGrammarStartKey @"s"
+#define CPGrammarRulesKey @"r"
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ self = [super init];
+
+ if (nil != self)
+ {
+ [self setStart:[aDecoder decodeObjectForKey:CPGrammarStartKey]];
+ [self setRules:[aDecoder decodeObjectForKey:CPGrammarRulesKey]];
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+ [aCoder encodeObject:[self start] forKey:CPGrammarStartKey];
+ [aCoder encodeObject:[self rules] forKey:CPGrammarRulesKey];
+}
+
- (void)dealloc
{
[start release];
+ [self setRules:nil];
[super dealloc];
}
View
2  CoreParse/Grammar/CPGrammarSymbol.h
@@ -13,7 +13,7 @@
*
* All grammar symbols carry a name which is used in constructing CPRules.
*/
-@interface CPGrammarSymbol : NSObject
+@interface CPGrammarSymbol : NSObject <NSCoding>
///---------------------------------------------------------------------------------------
/// @name Creating and Initialising a Rule
View
22 CoreParse/Grammar/CPGrammarSymbol.m
@@ -42,6 +42,28 @@ - (id)init
return [self initWithName:@"" isTerminal:NO];
}
+#define CPGrammarSymbolNameKey @"n"
+#define CPGrammarSymbolTerminalKey @"t"
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ self = [super init];
+
+ if (nil != self)
+ {
+ [self setName:[aDecoder decodeObjectForKey:CPGrammarSymbolNameKey]];
+ [self setTerminal:[aDecoder decodeBoolForKey:CPGrammarSymbolTerminalKey]];
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+ [aCoder encodeObject:[self name] forKey:CPGrammarSymbolNameKey];
+ [aCoder encodeBool:[self isTerminal] forKey:CPGrammarSymbolTerminalKey];
+}
+
- (BOOL)isEqual:(id)object
{
if ([object isKindOfClass:[CPGrammarSymbol class]])
View
2  CoreParse/Grammar/CPRule.h
@@ -19,7 +19,7 @@
* During parsing, a CPParser will inform its delegate of which CPRule it has matched to form a reduction. The tag
* property is provided to allow you to easily identify which rule has been matched.
*/
-@interface CPRule : NSObject
+@interface CPRule : NSObject <NSCoding>
///---------------------------------------------------------------------------------------
/// @name Creating and Initialising a Rule
View
28 CoreParse/Grammar/CPRule.m
@@ -88,6 +88,34 @@ - (id)init
return [self initWithName:@"" rightHandSideElements:[NSArray array]];
}
+#define CPRuleTagKey @"t"
+#define CPRuleNameKey @"n"
+#define CPRuleRHSElementsKey @"r"
+#define CPRuleRepresentitiveClassKey @"c"
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ self = [super init];
+
+ if (nil != self)
+ {
+ [self setTag:[aDecoder decodeIntegerForKey:CPRuleTagKey]];
+ [self setName:[aDecoder decodeObjectForKey:CPRuleNameKey]];
+ [self setRightHandSideElements:[aDecoder decodeObjectForKey:CPRuleRHSElementsKey]];
+ [self setRepresentitiveClass:NSClassFromString([aDecoder decodeObjectForKey:CPRuleRepresentitiveClassKey])];
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+ [aCoder encodeInteger:[self tag] forKey:CPRuleTagKey];
+ [aCoder encodeObject:[self name] forKey:CPRuleNameKey];
+ [aCoder encodeObject:[self rightHandSideElements] forKey:CPRuleRHSElementsKey];
+ [aCoder encodeObject:NSStringFromClass([self representitiveClass]) forKey:CPRuleRepresentitiveClassKey];
+}
+
- (void)dealloc
{
[name release];
View
2  CoreParse/Parsers/CPShiftReduceParser.h
@@ -15,6 +15,6 @@
*
* @warning Note that to create a parser you should use one of CPShiftReduceParser's subclasses.
*/
-@interface CPShiftReduceParser : CPParser
+@interface CPShiftReduceParser : CPParser <NSCoding>
@end
View
24 CoreParse/Parsers/CPShiftReduceParser.m
@@ -46,6 +46,30 @@ - (id)initWithGrammar:(CPGrammar *)grammar
return self;
}
+#define CPShiftReduceParserGrammarKey @"g"
+#define CPShiftReduceParserActionTableKey @"at"
+#define CPShiftReduceParserGotoTableKey @"gt"
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ self = [super initWithGrammar:[aDecoder decodeObjectForKey:CPShiftReduceParserGrammarKey]];
+
+ if (nil != self)
+ {
+ [self setActionTable:[aDecoder decodeObjectForKey:CPShiftReduceParserActionTableKey]];
+ [self setGotoTable:[aDecoder decodeObjectForKey:CPShiftReduceParserGotoTableKey]];
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+ [aCoder encodeObject:[self grammar] forKey:CPShiftReduceParserGrammarKey];
+ [aCoder encodeObject:[self actionTable] forKey:CPShiftReduceParserActionTableKey];
+ [aCoder encodeObject:[self gotoTable] forKey:CPShiftReduceParserGotoTableKey];
+}
+
- (void)dealloc
{
[actionTable release];
View
3  CoreParse/Parsers/CPShiftReduceParsers/CPShiftReduceAction.h
@@ -12,8 +12,7 @@
#import "CPGrammar.h"
-@interface CPShiftReduceAction : NSObject
-{}
+@interface CPShiftReduceAction : NSObject <NSCoding>
+ (id)shiftAction:(NSUInteger)shiftLocation;
+ (id)reduceAction:(CPRule *)reduction;
View
43 CoreParse/Parsers/CPShiftReduceParsers/CPShiftReduceAction.m
@@ -83,6 +83,49 @@ - (id)init
return self;
}
+#define CPShiftReduceActionTypeKey @"t"
+#define CPShiftReduceActionShiftKey @"s"
+#define CPShiftReduceActionRuleKey @"r"
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ self = [super init];
+
+ if (nil != self)
+ {
+ type = [aDecoder decodeIntForKey:CPShiftReduceActionTypeKey];
+ switch (type)
+ {
+ case kActionTypeShift:
+ details.shift = [aDecoder decodeIntegerForKey:CPShiftReduceActionShiftKey];
+ break;
+ case kActionTypeReduce:
+ details.reductionRule = [[aDecoder decodeObjectForKey:CPShiftReduceActionRuleKey] retain];
+ case kActionTypeAccept:
+ default:
+ break;
+ }
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+ [aCoder encodeInt:type forKey:CPShiftReduceActionTypeKey];
+ switch (type)
+ {
+ case kActionTypeShift:
+ [aCoder encodeInteger:details.shift forKey:CPShiftReduceActionShiftKey];
+ break;
+ case kActionTypeReduce:
+ [aCoder encodeObject:details.reductionRule forKey:CPShiftReduceActionRuleKey];
+ case kActionTypeAccept:
+ default:
+ break;
+ }
+}
+
- (void)dealloc
{
if (kActionTypeReduce == type)
View
2  CoreParse/Parsers/CPShiftReduceParsers/CPShiftReduceActionTable.h
@@ -13,7 +13,7 @@
#import "CPToken.h"
#import "CPGrammar.h"
-@interface CPShiftReduceActionTable : NSObject
+@interface CPShiftReduceActionTable : NSObject <NSCoding>
{}
- (id)initWithCapacity:(NSUInteger)capacity;
View
26 CoreParse/Parsers/CPShiftReduceParsers/CPShiftReduceActionTable.m
@@ -34,6 +34,32 @@ - (id)initWithCapacity:(NSUInteger)initCapacity
return self;
}
+#define CPShiftReduceActionTableTableKey @"t"
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ self = [super init];
+
+ if (nil != self)
+ {
+ NSArray *rows = [aDecoder decodeObjectForKey:CPShiftReduceActionTableTableKey];
+ capacity = [rows count];
+ table = malloc(capacity * sizeof(NSMutableDictionary *));
+ [rows getObjects:table range:NSMakeRange(0, capacity)];
+ for (NSUInteger i = 0; i < capacity; i++)
+ {
+ [table[i] retain];
+ }
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+ [aCoder encodeObject:[NSArray arrayWithObjects:table count:capacity] forKey:CPShiftReduceActionTableTableKey];
+}
+
- (void)dealloc
{
for (NSUInteger state = 0; state < capacity; state++)
View
2  CoreParse/Parsers/CPShiftReduceParsers/CPShiftReduceGotoTable.h
@@ -10,7 +10,7 @@
@class CPRule;
-@interface CPShiftReduceGotoTable : NSObject
+@interface CPShiftReduceGotoTable : NSObject <NSCoding>
{}
- (id)initWithCapacity:(NSUInteger)capacity;
View
19 CoreParse/Parsers/CPShiftReduceParsers/CPShiftReduceGotoTable.m
@@ -31,6 +31,25 @@ - (id)initWithCapacity:(NSUInteger)capacity
return self;
}
+#define CPShiftReduceGotoTableTableKey @"t"
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ self = [super init];
+
+ if (nil != self)
+ {
+ table = [[aDecoder decodeObjectForKey:CPShiftReduceGotoTableTableKey] retain];
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+ [aCoder encodeObject:table forKey:CPShiftReduceGotoTableTableKey];
+}
+
- (void)dealloc
{
[table release];
View
22 CoreParseTests/CoreParseTests.m
@@ -26,7 +26,6 @@ @implementation CoreParseTests
{
NSString *mapCssInput;
CPParser *mapCssParser;
- CPTokenStream *mapCSSTokenStream;
CPTokeniser *mapCssTokeniser;
}
@@ -92,8 +91,6 @@ - (void)setUp
@" line-width: 0.0;"
@"}";
- mapCSSTokenStream = [[mapCssTokeniser tokenise:mapCssInput] retain];
-
CPGrammar *grammar = [CPGrammar grammarWithStart:@"ruleset"
backusNaurForm:
@"ruleset ::= <rule>*;"
@@ -122,7 +119,6 @@ - (void)setUp
- (void)tearDown
{
[mapCssParser release];
- [mapCSSTokenStream release];
[mapCssTokeniser release];
[super tearDown];
@@ -323,7 +319,7 @@ - (void)testQuotedTokeniser
- (void)testMapCSSTokenisation
{
- if (![mapCSSTokenStream isEqualTo:[CPTokenStream tokenStreamWithTokens:[NSArray arrayWithObjects:
+ if (![[mapCssTokeniser tokenise:mapCssInput] isEqualTo:[CPTokenStream tokenStreamWithTokens:[NSArray arrayWithObjects:
[CPKeywordToken tokenWithKeyword:@"node"],
[CPKeywordToken tokenWithKeyword:@"["],
[CPIdentifierToken tokenWithIdentifier:@"highway"],
@@ -570,7 +566,7 @@ - (void)testBNFGrammarGeneration
- (void)testMapCSSParsing
{
- CPSyntaxTree *tree = [mapCssParser parse:mapCSSTokenStream];
+ CPSyntaxTree *tree = [mapCssParser parse:[mapCssTokeniser tokenise:mapCssInput]];
if (nil == tree)
{
@@ -583,7 +579,7 @@ - (void)testParallelParsing
CPTokenStream *stream = [[[CPTokenStream alloc] init] autorelease];
[NSThread detachNewThreadSelector:@selector(runMapCSSTokeniser:) toTarget:self withObject:stream];
CPSyntaxTree *tree1 = [mapCssParser parse:stream];
- CPSyntaxTree *tree2 = [mapCssParser parse:mapCSSTokenStream];
+ CPSyntaxTree *tree2 = [mapCssParser parse:[mapCssTokeniser tokenise:mapCssInput]];
if (![tree1 isEqual:tree2])
{
@@ -709,5 +705,17 @@ - (void)testEBNF
STFail(@"EBNF paren parser did not correctly parse its result", nil);
}
}
+
+- (void)testEncodingAndDecodingOfParsers
+{
+ NSData *d = [NSKeyedArchiver archivedDataWithRootObject:mapCssParser];
+ CPParser *mapCssParser2 = [NSKeyedUnarchiver unarchiveObjectWithData:d];
+ CPSyntaxTree *tree = [mapCssParser2 parse:[mapCssTokeniser tokenise:mapCssInput]];
+
+ if (nil == tree)
+ {
+ STFail(@"Failed to parse MapCSS", nil);
+ }
+}
@end
Please sign in to comment.
Something went wrong with that request. Please try again.