Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added the ability to ask the parser not to recover from an error.

  • Loading branch information...
commit 068cce66931c47c770bb89bce200bc37a7c83092 1 parent 882d13d
@beelsebob beelsebob authored
View
8 CoreParse.xcodeproj/project.pbxproj
@@ -73,7 +73,7 @@
1F530B921322814000F52EB5 /* CPRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F530B901322813F00F52EB5 /* CPRule.m */; };
1F6D44901348CC9500E982C7 /* CPLALR1Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F6D448E1348CC9500E982C7 /* CPLALR1Parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
1F6D44911348CC9600E982C7 /* CPLALR1Parser.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F6D448F1348CC9500E982C7 /* CPLALR1Parser.m */; };
- 1F893A1F14DEEBFC00316FF7 /* CPRecoveryAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F893A1D14DEEBFC00316FF7 /* CPRecoveryAction.h */; };
+ 1F893A1F14DEEBFC00316FF7 /* CPRecoveryAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F893A1D14DEEBFC00316FF7 /* CPRecoveryAction.h */; settings = {ATTRIBUTES = (Public, ); }; };
1F893A2014DEEBFC00316FF7 /* CPRecoveryAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F893A1E14DEEBFC00316FF7 /* CPRecoveryAction.m */; };
1F893A2314DEF40D00316FF7 /* CPTestErrorEvaluatorDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F893A2114DEF40D00316FF7 /* CPTestErrorEvaluatorDelegate.h */; };
1F893A2414DEF40D00316FF7 /* CPTestErrorEvaluatorDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F893A2214DEF40D00316FF7 /* CPTestErrorEvaluatorDelegate.m */; };
@@ -129,7 +129,7 @@
1F9F83A713B732AC006E939D /* Term.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F9F83A513B732AC006E939D /* Term.m */; };
1F9F83AC13B7CABA006E939D /* CPRHSItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F9F83AA13B7CAB9006E939D /* CPRHSItem.h */; };
1F9F83AD13B7CABA006E939D /* CPRHSItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F9F83AB13B7CABA006E939D /* CPRHSItem.m */; };
- 1FA68DA014DE98C4005519B9 /* CPErrorToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FA68D9E14DE98C4005519B9 /* CPErrorToken.h */; };
+ 1FA68DA014DE98C4005519B9 /* CPErrorToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FA68D9E14DE98C4005519B9 /* CPErrorToken.h */; settings = {ATTRIBUTES = (Public, ); }; };
1FA68DA114DE98C4005519B9 /* CPErrorToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FA68D9F14DE98C4005519B9 /* CPErrorToken.m */; };
1FA68DA514DE9D3D005519B9 /* CPTestErrorHandlingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FA68DA314DE9D3D005519B9 /* CPTestErrorHandlingDelegate.h */; };
1FA68DA614DE9D3D005519B9 /* CPTestErrorHandlingDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FA68DA414DE9D3D005519B9 /* CPTestErrorHandlingDelegate.m */; };
@@ -614,6 +614,8 @@
1FB3EB3A132D096900ACC453 /* CPGrammarSymbol.h in Headers */,
1F45A2E413422E1300092D78 /* CPJSONParser.h in Headers */,
1F3881DC1322ACE7000C8876 /* CPShiftReduceParser.h in Headers */,
+ 1FA68DA014DE98C4005519B9 /* CPErrorToken.h in Headers */,
+ 1F893A1F14DEEBFC00316FF7 /* CPRecoveryAction.h in Headers */,
1F3881E11322ADC9000C8876 /* CPShiftReduceAction.h in Headers */,
1F3881E51322AEE8000C8876 /* CPShiftReduceState.h in Headers */,
1F3881ED1322B66B000C8876 /* CPShiftReduceActionTable.h in Headers */,
@@ -631,9 +633,7 @@
1F9F83A613B732AC006E939D /* Term.h in Headers */,
1F9F83AC13B7CABA006E939D /* CPRHSItem.h in Headers */,
1FC00D5014544EDC00DC8D35 /* CPRHSItemResult.h in Headers */,
- 1FA68DA014DE98C4005519B9 /* CPErrorToken.h in Headers */,
1FA68DA514DE9D3D005519B9 /* CPTestErrorHandlingDelegate.h in Headers */,
- 1F893A1F14DEEBFC00316FF7 /* CPRecoveryAction.h in Headers */,
1F893A2314DEF40D00316FF7 /* CPTestErrorEvaluatorDelegate.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
View
172 CoreParse/Parsers/CPShiftReduceParser.m
@@ -87,108 +87,124 @@ - (BOOL)constructShiftReduceTables
return NO;
}
+#define kCPStopParsingException @"CPStopParsingException"
+
- (id)parse:(CPTokenStream *)tokenStream
{
- NSMutableArray *stateStack = [NSMutableArray arrayWithObject:[CPShiftReduceState shiftReduceStateWithObject:nil state:0]];
- CPToken *nextToken = [[tokenStream peekToken] retain];
- BOOL hasErrorToken = NO;
- while (1)
+ @try
{
- @autoreleasepool
+ NSMutableArray *stateStack = [NSMutableArray arrayWithObject:[CPShiftReduceState shiftReduceStateWithObject:nil state:0]];
+ CPToken *nextToken = [[tokenStream peekToken] retain];
+ BOOL hasErrorToken = NO;
+ while (1)
{
- CPShiftReduceAction *action = [self actionForState:[(CPShiftReduceState *)[stateStack lastObject] state] token:nextToken];
-
- if ([action isShiftAction])
+ @autoreleasepool
{
- [stateStack addObject:[CPShiftReduceState shiftReduceStateWithObject:nextToken state:[action newState]]];
- if (!hasErrorToken)
- {
- [tokenStream popToken];
- }
- [nextToken release];
- nextToken = [[tokenStream peekToken] retain];
- hasErrorToken = NO;
- }
- else if ([action isReduceAction])
- {
- CPRule *reductionRule = [action reductionRule];
- NSUInteger numElements = [[reductionRule rightHandSideElements] count];
- NSMutableArray *components = [NSMutableArray arrayWithCapacity:numElements];
- NSRange stateStackRange = NSMakeRange([stateStack count] - numElements, numElements);
- [stateStack enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:stateStackRange]
- options:NSEnumerationReverse
- usingBlock:^(CPShiftReduceState *state, NSUInteger idx, BOOL *stop)
- {
- id o = [state object];
- if ([o isKindOfClass:[CPRHSItemResult class]])
- {
- o = [(CPRHSItemResult *)o contents];
- }
- [components insertObject:o atIndex:0];
- }];
- [stateStack removeObjectsInRange:stateStackRange];
-
- CPSyntaxTree *tree = [CPSyntaxTree syntaxTreeWithRule:reductionRule children:components];
- id result = nil;
+ CPShiftReduceAction *action = [self actionForState:[(CPShiftReduceState *)[stateStack lastObject] state] token:nextToken];
- Class c = [reductionRule representitiveClass];
- if (nil != c)
+ if ([action isShiftAction])
{
- result = [(id<CPParseResult>)[c alloc] initWithSyntaxTree:tree];
- }
-
- if (nil == result)
- {
- result = tree;
- if ([[self delegate] respondsToSelector:@selector(parser:didProduceSyntaxTree:)])
+ [stateStack addObject:[CPShiftReduceState shiftReduceStateWithObject:nextToken state:[action newState]]];
+ if (!hasErrorToken)
{
- result = [[self delegate] parser:self didProduceSyntaxTree:tree];
+ [tokenStream popToken];
}
+ [nextToken release];
+ nextToken = [[tokenStream peekToken] retain];
+ hasErrorToken = NO;
}
-
- NSUInteger newState = [self gotoForState:[(CPShiftReduceState *)[stateStack lastObject] state] rule:reductionRule];
- [stateStack addObject:[CPShiftReduceState shiftReduceStateWithObject:result state:newState]];
- }
- else if ([action isAccept])
- {
- return [(CPShiftReduceState *)[stateStack lastObject] object];
- }
- else
- {
- CPRecoveryAction *recoveryAction = [self error:tokenStream expecting:[self acceptableTokenNamesForState:[(CPShiftReduceState *)[stateStack lastObject] state]]];
- if (nil == recoveryAction)
+ else if ([action isReduceAction])
{
- if ([nextToken isKindOfClass:[CPErrorToken class]] && [stateStack count] > 0)
+ CPRule *reductionRule = [action reductionRule];
+ NSUInteger numElements = [[reductionRule rightHandSideElements] count];
+ NSMutableArray *components = [NSMutableArray arrayWithCapacity:numElements];
+ NSRange stateStackRange = NSMakeRange([stateStack count] - numElements, numElements);
+ [stateStack enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:stateStackRange]
+ options:NSEnumerationReverse
+ usingBlock:^(CPShiftReduceState *state, NSUInteger idx, BOOL *stop)
+ {
+ id o = [state object];
+ if ([o isKindOfClass:[CPRHSItemResult class]])
+ {
+ o = [(CPRHSItemResult *)o contents];
+ }
+ [components insertObject:o atIndex:0];
+ }];
+ [stateStack removeObjectsInRange:stateStackRange];
+
+ CPSyntaxTree *tree = [CPSyntaxTree syntaxTreeWithRule:reductionRule children:components];
+ id result = nil;
+
+ Class c = [reductionRule representitiveClass];
+ if (nil != c)
{
- [stateStack removeLastObject];
+ result = [(id<CPParseResult>)[c alloc] initWithSyntaxTree:tree];
}
- else
+
+ if (nil == result)
{
- return nil;
+ result = tree;
+ if ([[self delegate] respondsToSelector:@selector(parser:didProduceSyntaxTree:)])
+ {
+ result = [[self delegate] parser:self didProduceSyntaxTree:tree];
+ }
}
+
+ NSUInteger newState = [self gotoForState:[(CPShiftReduceState *)[stateStack lastObject] state] rule:reductionRule];
+ [stateStack addObject:[CPShiftReduceState shiftReduceStateWithObject:result state:newState]];
+ }
+ else if ([action isAccept])
+ {
+ return [(CPShiftReduceState *)[stateStack lastObject] object];
}
else
{
- switch ([recoveryAction recoveryType])
+ CPRecoveryAction *recoveryAction = [self error:tokenStream expecting:[self acceptableTokenNamesForState:[(CPShiftReduceState *)[stateStack lastObject] state]]];
+ if (nil == recoveryAction)
{
- case CPRecoveryTypeAddToken:
- [nextToken release];
- nextToken = [[recoveryAction additionalToken] retain];
- hasErrorToken = YES;
- break;
- case CPRecoveryTypeRemoveToken:
- [tokenStream popToken];
- [nextToken release];
- nextToken = [[tokenStream peekToken] retain];
- hasErrorToken = NO;
- break;
- default:
- break;
+ if ([nextToken isKindOfClass:[CPErrorToken class]] && [stateStack count] > 0)
+ {
+ [stateStack removeLastObject];
+ }
+ else
+ {
+ return nil;
+ }
+ }
+ else
+ {
+ switch ([recoveryAction recoveryType])
+ {
+ case CPRecoveryTypeAddToken:
+ [nextToken release];
+ nextToken = [[recoveryAction additionalToken] retain];
+ hasErrorToken = YES;
+ break;
+ case CPRecoveryTypeRemoveToken:
+ [tokenStream popToken];
+ [nextToken release];
+ nextToken = [[tokenStream peekToken] retain];
+ hasErrorToken = NO;
+ break;
+ case CPRecoveryTypeBail:
+ [NSException raise:kCPStopParsingException format:@""];
+ break;
+ default:
+ break;
+ }
}
}
}
}
}
+ @catch (NSException *e)
+ {
+ if (![[e name] isEqualToString:kCPStopParsingException])
+ {
+ [e raise];
+ }
+ return nil;
+ }
}
- (CPRecoveryAction *)error:(CPTokenStream *)tokenStream expecting:(NSSet *)acceptableTokens
View
13 CoreParse/Parsers/Error Recovery/CPRecoveryAction.h
@@ -13,7 +13,8 @@
typedef enum
{
CPRecoveryTypeAddToken = 0,
- CPRecoveryTypeRemoveToken
+ CPRecoveryTypeRemoveToken ,
+ CPRecoveryTypeBail
} CPRecoveryType;
/**
@@ -47,6 +48,11 @@ typedef enum
+ (id)recoveryActionDeletingCurrentToken;
/**
+ * Allocates and initialise a new CPRecovery action asking the parser to stop immediately.
+ */
++ (id)recoveryActionStop;
+
+/**
* Initialises a CPRecoveryAction asking the parser to add a new token to the token stream.
*
* @param token The token to add to the stream.
@@ -61,4 +67,9 @@ typedef enum
*/
- (id)initWithDeleteAction;
+/**
+ * Initialises a CPRecoveryAction asking the parser to stop immediately.
+ */
+- (id)initWithStopAction;
+
@end
View
17 CoreParse/Parsers/Error Recovery/CPRecoveryAction.m
@@ -23,6 +23,11 @@ + (id)recoveryActionDeletingCurrentToken
return [[[self alloc] initWithDeleteAction] autorelease];
}
++ (id)recoveryActionStop
+{
+ return [[[self alloc] initWithStopAction] autorelease];
+}
+
- (id)initWithAdditionalToken:(CPToken *)token
{
self = [super init];
@@ -48,4 +53,16 @@ - (id)initWithDeleteAction
return self;
}
+- (id)initWithStopAction
+{
+ self = [super init];
+
+ if (nil != self)
+ {
+ [self setRecoveryType:CPRecoveryTypeBail];
+ }
+
+ return self;
+}
+
@end
Please sign in to comment.
Something went wrong with that request. Please try again.