⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 antlrbaserecognizer.m

📁 antlr最新版本V3源代码
💻 M
字号:
// [The "BSD licence"]// Copyright (c) 2006-2007 Kay Roepke// All rights reserved.//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions// are met:// 1. Redistributions of source code must retain the above copyright//    notice, this list of conditions and the following disclaimer.// 2. Redistributions in binary form must reproduce the above copyright//    notice, this list of conditions and the following disclaimer in the//    documentation and/or other materials provided with the distribution.// 3. The name of the author may not be used to endorse or promote products//    derived from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#import "ANTLRBaseRecognizer.h"#import "ANTLRBitSet.h"#import "ANTLRCommonToken.h"@class ANTLRRuleReturnScope;@implementation ANTLRBaseRecognizer- (id) init{	if (nil != (self = [super init])) {		following = [[NSMutableArray alloc] init];		errorRecovery = NO;		lastErrorIndex = -1;		failed = NO;		backtracking = 0;	}	return self;}- (void) dealloc{	[following release];	[super dealloc];}- (BOOL) isFailed{	return failed;}- (void) setIsFailed: (BOOL) flag{	failed = flag;}- (BOOL) isBacktracking{	return backtracking > 0;}- (int) backtrackingLevel{	return backtracking;}// reset the recognizer to the initial state. does not touch the token source!// this can be extended by the grammar writer to reset custom ivars- (void) reset{	errorRecovery = NO;	lastErrorIndex = -1;	failed = NO;	backtracking = 0;	[following removeAllObjects]; 	[ruleMemo removeAllObjects];}// match the next token on the input stream. try to recover with the FOLLOW set is there is a mismatch- (void) match:(id<ANTLRIntStream>)input 	 tokenType:(ANTLRTokenType) ttype		follow:(ANTLRBitSet *)follow{	ANTLRTokenType _ttype = [input LA:1];	if (_ttype == ttype) {		[input consume];		errorRecovery = NO;		failed = NO;		return;	}	if (backtracking > 0) {		failed = YES;		return;	}	[self mismatch:input tokenType:ttype follow:follow];}// prepare and exception and try to recover from a mismatch- (void) mismatch:(id<ANTLRIntStream>)aStream tokenType:(int)aTType follow:(ANTLRBitSet *)aBitset{	ANTLRMismatchedTokenException *mte = [ANTLRMismatchedTokenException exceptionWithTokenType:aTType stream:aStream];	[self recoverFromMismatchedToken:aStream exception:mte tokenType:aTType follow:aBitset];}// just consume the next symbol and reset the error ivars- (void) matchAny:(id<ANTLRIntStream>)input{	errorRecovery = NO;	failed = NO;	[input consume];}// everything failed. report the error- (void) reportError:(NSException *)e{	if (errorRecovery) {		return;	}	errorRecovery = YES;	[self displayRecognitionError:NSStringFromClass([self class]) tokenNames:[self tokenNames] exception:e];}// override to implement a different display strategy.- (void) displayRecognitionError:(NSString *)name tokenNames:(NSArray *)tokenNames exception:(NSException *)e{	NSLog(@"%@", [e description]);}// try to recover from a mismatch by resyncing- (void) recover:(id<ANTLRIntStream>)input exception:(NSException *)e{	if (lastErrorIndex == [input index]) {		[input consume];	}	lastErrorIndex = [input index];	ANTLRBitSet *followSet = [self computeErrorRecoverySet];	[self beginResync];	[self consumeUntil:input bitSet:followSet];	[self endResync];}// code smell...:(// hooks for debugger- (void) beginResync{}- (void) endResync{}- (void)beginBacktracking:(int)level{}- (void)endBacktracking:(int)level wasSuccessful:(BOOL)successful{}// end hooks for debugger- (ANTLRBitSet *)computeErrorRecoverySet{	return [self combineFollowsExact:NO];}- (ANTLRBitSet *)computeContextSensitiveRuleFOLLOW{	return [self combineFollowsExact:YES];}// compute a new FOLLOW set for recovery using the rules we have descended through- (ANTLRBitSet *)combineFollowsExact:(BOOL)exact{	ANTLRBitSet *followSet = [[[ANTLRBitSet alloc] init] autorelease];	int i;	for (i = [following count]-1; i >= 0; i--) {		ANTLRBitSet *localFollowSet = [following objectAtIndex:i];		[followSet orInPlace:localFollowSet];		if (exact && ![localFollowSet isMember:ANTLRTokenTypeEOR]) {			break;		}	}	[followSet remove:ANTLRTokenTypeEOR];	return followSet;}// delete one token and try to carry on.- (void) recoverFromMismatchedToken:(id<ANTLRIntStream>)input 						  exception:(NSException *)e 						  tokenType:(ANTLRTokenType)ttype 							 follow:(ANTLRBitSet *)follow{	if ([input LA:2] == ttype) {		[self reportError:e];		[self beginResync];		[input consume];		[self endResync];		[input consume];		return;	}	if (![self recoverFromMismatchedElement:input exception:e follow:follow]) {		@throw e;	}}- (void) recoverFromMismatchedSet:(id<ANTLRIntStream>)input						exception:(NSException *)e						   follow:(ANTLRBitSet *)follow{	// TODO - recovery is currently incomplete in ANTLR	if (![self recoverFromMismatchedElement:input exception:e follow:follow]) {		@throw e;	}}// this code handles single token insertion recovery- (BOOL) recoverFromMismatchedElement:(id<ANTLRIntStream>)input							exception:(NSException *)e							   follow:(ANTLRBitSet *)follow{	if (follow == nil) {		return NO;	}		// compute the viable symbols that can follow the current rule	ANTLRBitSet *localFollow = follow;	if ([follow isMember:ANTLRTokenTypeEOR]) {		ANTLRBitSet *viableTokensFollowingThisRule = [self computeContextSensitiveRuleFOLLOW];		ANTLRBitSet *localFollow = [follow or:viableTokensFollowingThisRule];		[localFollow remove:ANTLRTokenTypeEOR];	}	// if the current token could follow the missing token we tell the user and proceed with matching	if ([localFollow isMember:[input LA:1]]) {		[self reportError:e];		return YES;	}	// otherwise the match fails	return NO;}// used in resyncing to skip to next token of a known type- (void) consumeUntil:(id<ANTLRIntStream>)input			tokenType:(ANTLRTokenType)theTtype{	ANTLRTokenType ttype = [input LA:1];	while (ttype != ANTLRTokenTypeEOF && ttype != theTtype) {		[input consume];		ttype = [input LA:1];	}}// used in resyncing to skip to the next token whose type in the bitset- (void) consumeUntil:(id<ANTLRIntStream>)input			   bitSet:(ANTLRBitSet *)bitSet{	ANTLRTokenType ttype = [input LA:1];	while (ttype != ANTLRTokenTypeEOF && ![bitSet isMember:ttype]) {		[input consume];		ttype = [input LA:1];	}}- (void) pushFollow:(ANTLRBitSet *)follow{	[following addObject:follow];}- (NSArray *) ruleInvocationStack{	return [self ruleInvocationStack:nil recognizer:[self class]];}- (NSArray *) ruleInvocationStack:(id) exception					   recognizer:(Class) recognizerClass{	// todo	return [NSArray arrayWithObject:[@"not implemented yet: " stringByAppendingString:NSStringFromClass(recognizerClass)]];}- (NSArray *) tokenNames{	return tokenNames;}- (NSString *) grammarFileName{	return grammarFileName;}// pure convenience- (NSArray *) toStrings:(NSArray *)tokens{	if (tokens == nil ) {		return nil;	}	NSMutableArray *strings = [[[NSArray alloc] init] autorelease];	NSEnumerator *tokensEnumerator = [tokens objectEnumerator];	id value;	while (nil != (value = [tokensEnumerator nextObject])) {		[strings addObject:[(ANTLRToken *)value text]];	}	return strings;}// TODO need an Objective-C StringTemplate implementation for this- (NSArray *) toTemplates:(NSArray *)retvals{	return nil;#warning Templates are not yet supported in ObjC!}// the following methods handle the "memoization" caching functionality// they work by associating token indices with rule numbers.// that way, when we are about to parse a rule and have parsed the rule previously, e.g. in prediction,// we don't have to do it again but can simply return the token index to continue up parsing at.- (int) ruleMemoization:(int)ruleIndex startIndex:(int)ruleStartIndex{	if ([ruleMemo count] < ruleIndex) {		[ruleMemo setObject:[NSMutableDictionary dictionary] forKey:[NSNumber numberWithInt:ruleIndex]];	}	NSNumber *stopIndexI = [ruleMemo objectForKey:[NSNumber numberWithInt:ruleIndex]];	if (stopIndexI == nil) {		return ANTLR_MEMO_RULE_UNKNOWN;	} else {		return [stopIndexI intValue];	}}- (BOOL) alreadyParsedRule:(id<ANTLRIntStream>)input ruleIndex:(int)ruleIndex{	int stopIndex = [self ruleMemoization:ruleIndex startIndex:[input index]];	if (stopIndex == ANTLR_MEMO_RULE_UNKNOWN) {		return NO;	}	if (stopIndex == ANTLR_MEMO_RULE_FAILED) {		failed = YES;	} else {		[input seek:stopIndex+1];	}	return YES;}- (void) memoize:(id<ANTLRIntStream>)input	   ruleIndex:(int)ruleIndex	  startIndex:(int)ruleStartIndex{	int stopTokenIndex = failed ? ANTLR_MEMO_RULE_FAILED : [input index]-1;	if ([ruleMemo objectForKey:[NSNumber numberWithInt:ruleIndex]] == nil) {		[ruleMemo setObject:[NSNumber numberWithInt:stopTokenIndex] forKey:[NSNumber numberWithInt:ruleStartIndex]];	}}- (int) ruleMemoizationCacheSize{	int n = 0;		NSEnumerator *ruleEnumerator = [ruleMemo objectEnumerator];	id value;	while ((value = [ruleEnumerator nextObject])) {		n += [value count];	}	return n;}// call a syntactic predicate methods using its selector. this way we can support arbitrary synpreds.- (BOOL) evaluateSyntacticPredicate:(SEL)synpredFragment // stream:(id<ANTLRIntStream>)input{    backtracking++;	[self beginBacktracking:backtracking];	int start = [[self input] mark];    @try {        [self performSelector:synpredFragment];    }    @catch (ANTLRRecognitionException *re) {        NSLog(@"impossible synpred: %@", re);    }    BOOL success = !failed;    [[self input] rewind:start];	[self endBacktracking:backtracking wasSuccessful:success];	backtracking--;    failed = NO;    return success;}	@end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -