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

📄 antlrcommontreenodestream.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 "ANTLRCommonTreeNodeStream.h"#import "ANTLRCommonTreeNodeStreamState.h"#import "ANTLRTree.h"#import "ANTLRToken.h"@interface ANTLRTreeNavigationNode : ANTLRTree {}- (id) copyWithZone:(NSZone *)aZone;@end@interface ANTLRTreeNavigationNodeDown : ANTLRTreeNavigationNode {}- (int) tokenType;- (NSString *) description;@end@interface ANTLRTreeNavigationNodeUp : ANTLRTreeNavigationNode {}- (int) tokenType;- (NSString *) description;@end@interface ANTLRTreeNavigationNodeEOF : ANTLRTreeNavigationNode {}- (int) tokenType;- (NSString *) description;@end#pragma mark -static ANTLRTreeNavigationNodeDown *downNavigationNode;static ANTLRTreeNavigationNodeUp *upNavigationNode;static ANTLRTreeNavigationNodeEOF *eofNavigationNode;#define INITIAL_LOOKAHEAD_BUFFER_SIZE 5@implementation ANTLRCommonTreeNodeStream+ (void) initialize{	downNavigationNode = [[ANTLRTreeNavigationNodeDown alloc] init];	upNavigationNode = [[ANTLRTreeNavigationNodeUp alloc] init];	eofNavigationNode = [[ANTLRTreeNavigationNodeEOF alloc] init];}- (id) initWithTree:(ANTLRCommonTree *)theTree;{	return [self initWithTree:theTree treeAdaptor:nil];}- (id) initWithTree:(ANTLRCommonTree *)theTree treeAdaptor:(ANTLRCommonTreeAdaptor *)theAdaptor;{	if ((self = [super init]) != nil) {		[self setRoot:theTree];		if (!theAdaptor) 			[self setTreeAdaptor:[[[ANTLRCommonTreeAdaptor alloc] init] autorelease]];		else			[self setTreeAdaptor:theAdaptor];		nodeStack = [[NSMutableArray alloc] init];		indexStack = [[NSMutableArray alloc] init];		markers = [[NSMutableArray alloc] initWithObjects:[NSNull null], nil];	// markers is one based - maybe fix this later		lookahead = [[NSMutableArray alloc] initWithCapacity:INITIAL_LOOKAHEAD_BUFFER_SIZE];	// lookahead is filled with [NSNull null] in -reset		[self reset];	}	return self;}- (void) dealloc{	[self setRoot:nil];	[self setTreeAdaptor:nil];		[nodeStack release];	nodeStack = nil;	[indexStack release];	indexStack = nil;	[markers release];		markers = nil;	[lookahead release];	lookahead = nil;		[super dealloc];}- (void) reset;{	currentNode = root;	previousNode = nil;	currentChildIndex = -1;	absoluteNodeIndex = -1;	head = tail = 0;	[nodeStack removeAllObjects];	[indexStack removeAllObjects];	[markers removeAllObjects];	[markers addObject:[NSNull null]];	// markers are 1-based.	[lookahead removeAllObjects];	// TODO: this is not ideal, but works for now. optimize later	int i;	for (i = 0; i < INITIAL_LOOKAHEAD_BUFFER_SIZE; i++)		[lookahead addObject:[NSNull null]];}#pragma mark ANTLRTreeNodeStream conformance- (id) LT:(int)k;{	if (k == -1)		return previousNode;	if (k < 0)		@throw [NSException exceptionWithName:@"ANTLRTreeException" reason:@"cannot look back more than one node in a tree" userInfo:nil];	if (k == 0)		return [ANTLRTree invalidNode];	[self fillBufferWithLookahead:k];	return [lookahead objectAtIndex:(head+k-1) % [lookahead count]];}- (id<ANTLRTreeAdaptor>) treeAdaptor;{	return treeAdaptor;}- (void) setUsesUniqueNavigationNodes:(BOOL)flag;{	shouldUseUniqueNavigationNodes = flag;}#pragma mark ANTLRIntStream conformance- (void) consume;{	[self fillBufferWithLookahead:1];	absoluteNodeIndex++;	previousNode = [lookahead objectAtIndex:head];	head = (head+1) % [lookahead count];}- (int) LA:(unsigned int) i;{	ANTLRCommonTree *node = [self LT:i];	if (!node) 		return ANTLRTokenTypeInvalid;	int ttype = [node tokenType];	return ttype;}- (unsigned int) mark;{	ANTLRCommonTreeNodeStreamState *state = [[ANTLRCommonTreeNodeStreamState alloc] init];	[state setCurrentNode:currentNode];	[state setPreviousNode:previousNode];	[state setIndexStackSize:[indexStack count]];	[state setNodeStackSize:[nodeStack count]];	[state setCurrentChildIndex:currentChildIndex];	[state setAbsoluteNodeIndex:absoluteNodeIndex];	unsigned int lookaheadSize = [self lookaheadSize];	int k;	for ( k = 1; k <= lookaheadSize; k++) {		[state addToLookahead:[self LT:k]];	}	[markers addObject:state];	[state release];	return [markers count];}- (unsigned int) index;{	return absoluteNodeIndex + 1;}- (void) rewind:(unsigned int) marker;{	if ( [markers count] < marker ) {		return;	}	ANTLRCommonTreeNodeStreamState *state = [[markers objectAtIndex:marker-1] retain];	[markers removeObjectAtIndex:marker-1];	absoluteNodeIndex = [state absoluteNodeIndex];	currentChildIndex = [state currentChildIndex];	currentNode = [state currentNode];	previousNode = [state previousNode];	// drop node and index stacks back to old size	[nodeStack removeObjectsInRange:NSMakeRange([state nodeStackSize], [nodeStack count]-[state nodeStackSize])];	[indexStack removeObjectsInRange:NSMakeRange([state indexStackSize], [indexStack count]-[state indexStackSize])];		head = tail = 0; // wack lookahead buffer and then refill	[lookahead release];	lookahead = [[NSMutableArray alloc] initWithArray:[state lookahead]];	tail = [lookahead count];	// make some room after the restored lookahead, so that the above line is not a bug ;)	// this also ensures that a subsequent -addLookahead: will not immediately need to resize the buffer	[lookahead addObjectsFromArray:[NSArray arrayWithObjects:[NSNull null], [NSNull null], [NSNull null], [NSNull null], [NSNull null], nil]];}- (void) rewind{	[self rewind:[markers count]];}- (void) release:(unsigned int) marker;{	@throw [NSException exceptionWithName:@"ANTLRTreeException" reason:@"-release: is not supported for trees" userInfo:nil];}- (void) seek:(unsigned int) index;{	if ( index < [self index] )		@throw [NSException exceptionWithName:@"ANTLRTreeException" reason:@"cannot seek backwards in tree streams" userInfo:nil];	while ( [self index] < index ) {		[self consume];	}}- (unsigned int) count;{	return absoluteNodeIndex + 1;	// not entirely correct, but cheap.}#pragma mark Lookahead Handling- (void) addLookahead:(id<ANTLRTree>)aNode;{	[lookahead replaceObjectAtIndex:tail withObject:aNode];	tail = (tail+1) % [lookahead count];		if ( tail == head ) {		NSMutableArray *newLookahead = [[NSMutableArray alloc] initWithCapacity:[lookahead count]*2];				NSRange headRange = NSMakeRange(head, [lookahead count]-head);		NSRange tailRange = NSMakeRange(0, tail);				[newLookahead addObjectsFromArray:[lookahead objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:headRange]]];		[newLookahead addObjectsFromArray:[lookahead objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:tailRange]]];				unsigned int i;		unsigned int lookaheadCount = [newLookahead count];		for (i = 0; i < lookaheadCount; i++)			[newLookahead addObject:[NSNull null]];		[lookahead release];		lookahead = newLookahead;				head = 0;		tail = lookaheadCount;	// tail is the location the _next_ lookahead node will end up in, not the last element's idx itself!	}	}- (unsigned int) lookaheadSize;{	return tail < head		? ([lookahead count] - head + tail) 		: (tail - head);}- (void) fillBufferWithLookahead:(int)k;{	unsigned int n = [self lookaheadSize];	unsigned int i;	id lookaheadObject = self; // any valid object would do.	for (i=1; i <= k-n && lookaheadObject != nil; i++) {		lookaheadObject = [self nextObject];	}}- (id) nextObject{	// NOTE: this could/should go into an NSEnumerator subclass for treenode streams.	if (currentNode == nil) {		[self addLookahead:eofNavigationNode];		return nil;	}	if (currentChildIndex == -1) {		return [self handleRootNode];	}	if (currentChildIndex < [currentNode childCount]) {		return [self visitChild:currentChildIndex];	}	[self walkBackToMostRecentNodeWithUnvisitedChildren];	if (currentNode != nil) {		return [self visitChild:currentChildIndex];	}		return nil;}	#pragma mark Node visiting- (ANTLRCommonTree *) handleRootNode;{	ANTLRCommonTree *node = currentNode;	currentChildIndex = 0;	if ([node isEmpty]) {		node = [self visitChild:currentChildIndex];	} else {		[self addLookahead:node];		if ([currentNode childCount] == 0) {			currentNode = nil;		}	}	return node;}- (ANTLRCommonTree *) visitChild:(int)childNumber;{	ANTLRCommonTree *node = nil;		[nodeStack addObject:currentNode];	[indexStack addObject:[NSNumber numberWithInt:childNumber]];	if (childNumber == 0 && ![currentNode isEmpty])		[self addNavigationNodeWithType:ANTLRTokenTypeDOWN];	currentNode = [currentNode childAtIndex:childNumber];	currentChildIndex = 0;	node = currentNode;  // record node to return	[self addLookahead:node];	[self walkBackToMostRecentNodeWithUnvisitedChildren];	return node;}- (void) walkBackToMostRecentNodeWithUnvisitedChildren;{	while (currentNode != nil && currentChildIndex >= [currentNode childCount])	{		currentNode = (ANTLRCommonTree *)[nodeStack lastObject];		[nodeStack removeLastObject];		currentChildIndex = [(NSNumber *)[indexStack lastObject] intValue];		[indexStack removeLastObject];		currentChildIndex++; // move to next child		if (currentChildIndex >= [currentNode childCount]) {			if (![currentNode isEmpty]) {				[self addNavigationNodeWithType:ANTLRTokenTypeUP];			}			if (currentNode == root) { // we done yet?				currentNode = nil;			}		}	}	}- (void) addNavigationNodeWithType:(int)tokenType;{	// TODO: this currently ignores shouldUseUniqueNavigationNodes.	switch (tokenType) {		case ANTLRTokenTypeDOWN: {			[self addLookahead:downNavigationNode];			break;		}		case ANTLRTokenTypeUP: {			[self addLookahead:upNavigationNode];			break;		}	}}#pragma mark Accessors- (ANTLRCommonTree *) root{    return root; }- (void) setRoot: (ANTLRCommonTree *) aRoot{    if (root != aRoot) {        [aRoot retain];        [root release];        root = aRoot;    }}- (void) setTreeAdaptor: (ANTLRCommonTreeAdaptor *) aTreeAdaptor{    if (treeAdaptor != aTreeAdaptor) {        [aTreeAdaptor retain];        [treeAdaptor release];        treeAdaptor = aTreeAdaptor;    }}@end#pragma mark -@implementation ANTLRTreeNavigationNode- (id) copyWithZone:(NSZone *)aZone{	return nil;}@end@implementation ANTLRTreeNavigationNodeDown- (int) tokenType { return ANTLRTokenTypeDOWN; }- (NSString *) description { return @"DOWN"; }@end@implementation ANTLRTreeNavigationNodeUp- (int) tokenType { return ANTLRTokenTypeUP; }- (NSString *) description { return @"UP"; }@end@implementation ANTLRTreeNavigationNodeEOF- (int) tokenType { return ANTLRTokenTypeEOF; }- (NSString *) description { return @"EOF"; }@end

⌨️ 快捷键说明

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