Browse files

Parsers now produce information about which tokens are valid to allow…

… the parser to continue when an error occurs.
  • Loading branch information...
1 parent 1e3f868 commit a28edd2b19833856f0648aeda04f56199007097e @beelsebob beelsebob committed Feb 12, 2012
View
16 CoreParse/Parsers/CPParser.h
@@ -58,13 +58,25 @@
/**
* Called when the parser encounters a token for which it can not shift, reduce or accept.
*
- * @param parser The parser which produced the syntax tree.
- * @param inputStream The input stream containing the token the parser could not cope with.
+ * @param parser The parser which produced the syntax tree.
+ * @param inputStream The input stream containing the token the parser could not cope with.
* @return An action to take to recover from the parse error or nil. If the action is nil, and the problematic token is a CPErrorToken
* the parse stack is unwound a step for the parent rule to deal with the error.
+ * @bug Warning this method is deprecated, use -parser:didEncounterErrorOnInput:expecting: instead.
*/
- (CPRecoveryAction *)parser:(CPParser *)parser didEncounterErrorOnInput:(CPTokenStream *)inputStream;
+/**
+ * Called when the parser encounters a token for which it can not shift, reduce or accept.
+ *
+ * @param parser The parser which produced the syntax tree.
+ * @param inputStream The input stream containing the token the parser could not cope with.
+ * @param acceptableTokens A set of token names that would have allowed the parser to continue in its current state.
+ * @return An action to take to recover from the parse error or nil. If the action is nil, and the problematic token is a CPErrorToken
+ * the parse stack is unwound a step for the parent rule to deal with the error.
+ */
+- (CPRecoveryAction *)parser:(CPParser *)parser didEncounterErrorOnInput:(CPTokenStream *)inputStream expecting:(NSSet *)acceptableTokens;
+
@end
/**
View
18 CoreParse/Parsers/CPShiftReduceParser.m
@@ -20,9 +20,10 @@
@interface CPShiftReduceParser ()
- (CPShiftReduceAction *)actionForState:(NSUInteger)state token:(CPToken *)token;
+- (NSSet *)acceptableTokenNamesForState:(NSUInteger)state;
- (NSUInteger)gotoForState:(NSUInteger)state rule:(CPRule *)rule;
-- (CPRecoveryAction *)error:(CPTokenStream *)tokenStream;
+- (CPRecoveryAction *)error:(CPTokenStream *)tokenStream expecting:(NSSet *)acceptableTokens;
@end
@@ -154,7 +155,7 @@ - (id)parse:(CPTokenStream *)tokenStream
}
else
{
- CPRecoveryAction *recoveryAction = [self error:tokenStream];
+ CPRecoveryAction *recoveryAction = [self error:tokenStream expecting:[self acceptableTokenNamesForState:[(CPShiftReduceState *)[stateStack lastObject] state]]];
if (nil == recoveryAction)
{
if ([nextToken isKindOfClass:[CPErrorToken class]] && [stateStack count] > 0)
@@ -190,9 +191,13 @@ - (id)parse:(CPTokenStream *)tokenStream
}
}
-- (CPRecoveryAction *)error:(CPTokenStream *)tokenStream
+- (CPRecoveryAction *)error:(CPTokenStream *)tokenStream expecting:(NSSet *)acceptableTokens
{
- if ([[self delegate] respondsToSelector:@selector(parser:didEncounterErrorOnInput:)])
+ if ([[self delegate] respondsToSelector:@selector(parser:didEncounterErrorOnInput:expecting:)])
+ {
+ return [[self delegate] parser:self didEncounterErrorOnInput:tokenStream expecting:acceptableTokens];
+ }
+ else if ([[self delegate] respondsToSelector:@selector(parser:didEncounterErrorOnInput:)])
{
return [[self delegate] parser:self didEncounterErrorOnInput:tokenStream];
}
@@ -208,6 +213,11 @@ - (CPShiftReduceAction *)actionForState:(NSUInteger)state token:(CPToken *)token
return [[self actionTable] actionForState:state token:token];
}
+- (NSSet *)acceptableTokenNamesForState:(NSUInteger)state
+{
+ return [[self actionTable] acceptableTokenNamesForState:state];
+}
+
- (NSUInteger)gotoForState:(NSUInteger)state rule:(CPRule *)rule
{
return [[self gotoTable] gotoForState:state rule:rule];
View
1 CoreParse/Parsers/CPShiftReduceParsers/CPShiftReduceActionTable.h
@@ -21,6 +21,7 @@
- (BOOL)setAction:(CPShiftReduceAction *)action forState:(NSUInteger)state name:(NSString *)token;
- (CPShiftReduceAction *)actionForState:(NSUInteger)state token:(CPToken *)token;
+- (NSSet *)acceptableTokenNamesForState:(NSUInteger)state;
- (NSString *)descriptionWithGrammar:(CPGrammar *)g;
View
13 CoreParse/Parsers/CPShiftReduceParsers/CPShiftReduceActionTable.m
@@ -87,6 +87,19 @@ - (CPShiftReduceAction *)actionForState:(NSUInteger)state token:(CPToken *)token
return [table[state] objectForKey:token.name];
}
+- (NSSet *)acceptableTokenNamesForState:(NSUInteger)state
+{
+ NSMutableSet *toks = [NSMutableSet set];
+ for (NSString *tok in table[state])
+ {
+ if (nil != [table[state] objectForKey:tok])
+ {
+ [toks addObject:tok];
+ }
+ }
+ return [[toks copy] autorelease];
+}
+
- (NSString *)description
{
if (capacity > 0)
View
2 CoreParseTests/CPTestErrorEvaluatorDelegate.m
@@ -41,7 +41,7 @@ - (id)parser:(CPParser *)parser didProduceSyntaxTree:(CPSyntaxTree *)syntaxTree
}
}
-- (CPRecoveryAction *)parser:(CPParser *)parser didEncounterErrorOnInput:(CPTokenStream *)inputStream
+- (CPRecoveryAction *)parser:(CPParser *)parser didEncounterErrorOnInput:(CPTokenStream *)inputStream expecting:(NSSet *)acceptableTokens
{
return [CPRecoveryAction recoveryActionWithAdditionalToken:[CPErrorToken errorWithMessage:@"Expected expression"]];
}
View
2 CoreParseTests/CPTestErrorHandlingDelegate.m
@@ -34,7 +34,7 @@ - (id)parser:(CPParser *)parser didProduceSyntaxTree:(CPSyntaxTree *)syntaxTree
return syntaxTree;
}
-- (CPRecoveryAction *)parser:(CPParser *)parser didEncounterErrorOnInput:(CPTokenStream *)inputStream
+- (CPRecoveryAction *)parser:(CPParser *)parser didEncounterErrorOnInput:(CPTokenStream *)inputStream expecting:(NSSet *)acceptableTokens
{
hasEncounteredError = YES;
return [CPRecoveryAction recoveryActionDeletingCurrentToken];

0 comments on commit a28edd2

Please sign in to comment.