Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Beginnings of porting the Obj-C code to Obj-J.

  • Loading branch information...
commit 98b7f3cf61834f3d908fbe1fa347583bafa21b6d 0 parents
Ross Boucher authored
24 TDAlternationParser.j
@@ -0,0 +1,24 @@
+
+@import "TDCollectionParser.j"
+@import "TDAssembly.j"
+
+@implementation TDAlternation : TDCollectionParser
+{
+}
+
++ (id)alternation
+{
+ return [[self alloc] init];
+}
+
+- (CPSet)allMatchesFor:(CPSet)inAssemblies
+{
+ var outAssemblies = [CPSet set];
+
+ for (var i=0, count=[subparsers count]; i<count; i++)
+ [outAssemblies unionSet:[subparsers[i] matchAndAssemble:inAssemblies]];
+
+ return outAssemblies;
+}
+
+@end
163 TDAssembly.j
@@ -0,0 +1,163 @@
+
+@import <Foundation/Foundation.j>
+
+TDAssemblyDefaultDelimiter = @"/";
+
+@interface TDAssembly : CPObject
+{
+ CPArray stack;
+ id target;
+ unsigned index;
+ CPString string;
+ CPString defaultDelimiter;
+}
+
++ (id)assemblyWithString:(CPString)s
+{
+ return [[self alloc] initWithString:s];
+}
+
+- (id)init
+{
+ return [self initWithString:nil];
+}
+
+- (id)initWithString:(CPString)s
+{
+ if self = [super init] {
+ stack = [];
+ string = s;
+ }
+
+ return self;
+}
+
+// this private intializer exists simply to improve the performance of the -copyWithZone: method.
+// note flow *does not* go thru the designated initializer above. however, that ugliness is worth it cuz
+// the perf of -copyWithZone: in this class is *vital* to the framework's performance
+- (id)_init
+{
+ return [super init];
+}
+
+// this method diverges from coding standards cuz it is vital to the entire framework's performance
+- (id)copy
+{
+ var a = [[[self class] alloc] _init];
+
+ a.stack = [stack copy];
+ a.string = string;
+ a.index = index;
+
+ if (defaultDelimiter)
+ a.defaultDelimiter = defaultDelimiter;
+
+ if (target)
+ a.target = [target copy]
+
+ return a;
+}
+
+- (id)next {
+ //NSAssert1(0, @"-[TDAssembly %s] must be overriden", _cmd);
+ return nil;
+}
+
+- (BOOL)hasMore {
+ //NSAssert1(0, @"-[TDAssembly %s] must be overriden", _cmd);
+ return NO;
+}
+
+- (CPString)consumedObjectsJoinedByString:(CPString)delimiter {
+ //NSAssert1(0, @"-[TDAssembly %s] must be overriden", _cmd);
+ return nil;
+}
+
+- (CPString)remainingObjectsJoinedByString:(CPString)delimiter {
+ //NSAssert1(0, @"-[TDAssembly %s] must be overriden", _cmd);
+ return nil;
+}
+
+- (unsigned)length {
+ //NSAssert1(0, @"-[TDAssembly %s] must be overriden", _cmd);
+ return 0;
+}
+
+- (unsigned)objectsConsumed {
+ //NSAssert1(0, @"-[TDAssembly %s] must be overriden", _cmd);
+ return 0;
+}
+
+- (unsigned)objectsRemaining {
+ //NSAssert1(0, @"-[TDAssembly %s] must be overriden", _cmd);
+ return 0;
+}
+
+- (id)peek {
+ //NSAssert1(0, @"-[TDAssembly %s] must be overriden", _cmd);
+ return nil;
+}
+
+- (id)pop
+{
+ var result = nil;
+ if (stack.count) {
+ result = [stack lastObject];
+ [stack removeLastObject];
+ }
+ return result;
+}
+
+- (void)push:(id)object
+{
+ if (object) {
+ [stack addObject:object];
+ }
+}
+
+- (BOOL)isStackEmpty {
+ return 0 === stack.count;
+}
+
+
+- (CPArray)objectsAbove:(id)fence
+{
+ var result = [];
+
+ while (stack.count) {
+ var obj = [self pop];
+
+ if ([obj isEqual:fence]) {
+ [self push:obj];
+ break;
+ } else {
+ [result addObject:obj];
+ }
+ }
+
+ return result;
+}
+
+- (CPString)description
+{
+ var s = "[",
+ i = 0,
+ length = stack.count;
+
+ for (;i<length;i++) {
+ s = s + [obj description];
+ if (len - 1 !== i++) {
+ s = s + ", ";
+ }
+ }
+
+ s = s + "]";
+
+ var d = defaultDelimiter ? defaultDelimiter : TDAssemblyDefaultDelimiter;
+
+ s = s + [self consumedObjectsJoinedByString:d] + "^" + [self remainingObjectsJoinedByString:d];
+
+ return s;
+}
+
+@end
41 TDCollectionParser.j
@@ -0,0 +1,41 @@
+
+@import "TDParser.j"
+
+@implementation TDCollectionParser : TDParser
+{
+ CPArray subparsers @accessors;
+}
+
+- (id)init
+{
+ if (self = [super init]) {
+ self.subparsers = [];
+ }
+
+ return self;
+}
+
+- (void)add:(TDParser)p
+{
+ [subparsers addObject:p];
+}
+
+- (TDParser)parserNamed:(CPString)s
+{
+ if (name === s)
+ return self;
+ else
+ {
+ for (var i=0, length = [subparsers count]; i<length; i++)
+ {
+ var sub = [subparsers[i] parserNamed:s];
+
+ if (sub)
+ return sub;
+ }
+ }
+
+ return nil;
+}
+
+@end
18 TDEmpty.j
@@ -0,0 +1,18 @@
+
+@import "TDParser.j"
+
+@implementation TDEmpty : TDParser {
+
+}
+
++ (id)empty
+{
+ return [[self alloc] init];
+}
+
+- (CPSet)allMatchesFor:(CPSet)inAssemblies
+{
+ return inAssemblies;
+}
+
+@end
59 TDParseKit.j
@@ -0,0 +1,59 @@
+@import <Foundation/Foundation.j>
+
+// io
+//@import <TDParseKit/TDReader.j>
+
+// parse
+//@import <TDParseKit/TDParser.j>
+//@import <TDParseKit/TDAssembly.j>
+//@import <TDParseKit/TDSequence.j>
+//@import <TDParseKit/TDCollectionParser.j>
+//@import <TDParseKit/TDAlternation.j>
+//@import <TDParseKit/TDRepetition.j>
+//@import <TDParseKit/TDEmpty.j>
+//@import <TDParseKit/TDTerminal.j>
+//@import <TDParseKit/TDTrack.j>
+//@import <TDParseKit/TDTrackException.j>
+
+// factory
+//@import <TDParseKit/TDParserFactory.j>
+
+//chars
+//@import <TDParseKit/TDCharacterAssembly.j>
+//@import <TDParseKit/TDChar.j>
+//@import <TDParseKit/TDSpecificChar.j>
+//@import <TDParseKit/TDLetter.j>
+//@import <TDParseKit/TDDigit.j>
+
+// tokens
+//@import <TDParseKit/TDToken.j>
+//@import <TDParseKit/TDTokenizer.j>
+//@import <TDParseKit/TDTokenArraySource.j>
+//@import <TDParseKit/TDTokenAssembly.j>
+//@import <TDParseKit/TDTokenizerState.j>
+//@import <TDParseKit/TDNumberState.j>
+//@import <TDParseKit/TDQuoteState.j>
+//@import <TDParseKit/TDCommentState.j>
+//@import <TDParseKit/TDSingleLineCommentState.j>
+//@import <TDParseKit/TDMultiLineCommentState.j>
+//@import <TDParseKit/TDSymbolNode.j>
+//@import <TDParseKit/TDSymbolRootNode.j>
+//@import <TDParseKit/TDSymbolState.j>
+//@import <TDParseKit/TDWordState.j>
+//@import <TDParseKit/TDWhitespaceState.j>
+//@import <TDParseKit/TDWord.j>
+//@import <TDParseKit/TDNum.j>
+//@import <TDParseKit/TDQuotedString.j>
+//@import <TDParseKit/TDSymbol.j>
+//@import <TDParseKit/TDComment.j>
+//@import <TDParseKit/TDLiteral.j>
+//@import <TDParseKit/TDCaseInsensitiveLiteral.j>
+//@import <TDParseKit/TDAny.j>
+
+// ext
+//@import <TDParseKit/TDScientificNumberState.j>
+//@import <TDParseKit/TDWordOrReservedState.j>
+//@import <TDParseKit/TDUppercaseWord.j>
+//@import <TDParseKit/TDLowercaseWord.j>
+//@import <TDParseKit/TDReservedWord.j>
+//@import <TDParseKit/TDNonReservedWord.j>
106 TDParser.j
@@ -0,0 +1,106 @@
+
+@import <Foundation/Foundation.j>
+@import "TDAssembly.j"
+
+@interface TDParser : CPObject
+{
+ id assembler;
+ SEL selector;
+ CPString name;
+}
+
++ (id)parser
+{
+ return [[self alloc] init];
+}
+
+- (id)init
+{
+ return self = [super init];
+}
+
+- (void)setAssembler:(id)a selector:(SEL)sel
+{
+ [self setAssembler:a];
+ [self setSelector:sel];
+}
+
+- (TDParser)parserNamed:(CPString)s
+{
+ if (name === s)
+ return self;
+
+ return nil;
+}
+
+- (CPSet)allMatchesFor:(CPSet)inAssemblies
+{
+ //NSAssert1(0, @"-[TDParser %s] must be overriden", _cmd);
+ return nil;
+}
+
+- (TDAssembly)bestMatchFor:(TDAssembly)a
+{
+ var initialState = [CPSet setWithObject:a],
+ finalState = [self matchAndAssemble:initialState];
+
+ return [self best:finalState];
+}
+
+- (TDAssembly)completeMatchFor:(TDAssembly)a
+{
+ var best = [self bestMatchFor:a];
+
+ if (best && ![best hasMore])
+ return best;
+
+ return nil;
+}
+
+- (CPSet)matchAndAssemble:(CPSet)inAssemblies
+{
+ var outAssemblies = [self allMatchesFor:inAssemblies];
+
+ if (assembler) {
+ //NSAssert2([assembler respondsToSelector:selector], @"provided assembler %@ should respond to %s", assembler, selector);
+ var values = [outAssemblies allValues],
+ length = [values count];
+
+ for (var i=0; i<length; i++) {
+ [assembler performSelector:selector withObject:values[i]];
+ }
+ }
+
+ return outAssemblies;
+}
+
+- (TDAssembly)best:(CPSet)inAssemblies
+{
+ var best = nil,
+ values = [inAssemblies allValues],
+ length = [values count];
+
+ for (var i=0; i<length; i++) {
+ var a = values[i];
+
+ if (![a hasMore]) {
+ best = a;
+ break;
+ }
+
+ if (!best || a.objectsConsumed > best.objectsConsumed)
+ best = a;
+ }
+
+ return best;
+}
+
+- (CPString)description
+{
+ if (name.length)
+ return [CPString stringWithFormat:@"%@ (%@)", [self className], name];
+ else
+ return [CPString stringWithFormat:@"%@", [self className]];
+}
+
+@end
55 TDReader.j
@@ -0,0 +1,55 @@
+
+@import <Foundation/Foundation.j>
+
+@implementation TDReader : CPObject
+{
+ CPString string;
+ unsigned cursor;
+ unsigned length;
+}
+
+- (id)init
+{
+ return [self initWithString:nil];
+}
+
+- (id)initWithString:(CPString)s
+{
+ if (self = [super init]) {
+ [self setString:s];
+ }
+
+ return self;
+}
+
+- (CPString)string
+{
+ return string;
+}
+
+- (void)setString:(CPString)s
+{
+ if (string !== s) {
+ string = s;
+ length = string ? string.length : 0;
+ }
+
+ // reset cursor
+ cursor = 0;
+}
+
+- (unsigned)read
+{
+ if (0 === length || cursor > length - 1) {
+ return -1;
+ }
+
+ return string.charAt(cursor++);
+}
+
+- (void)unread
+{
+ cursor = (0 === cursor) ? 0 : cursor - 1;
+}
+
+@end
67 TDRepetition.j
@@ -0,0 +1,67 @@
+
+@import "TDParser.j"
+@import "TDAssembly.j"
+
+@implementation TDRepetition : TDParser
+{
+ TDParser subparser;
+ id preassembler;
+ SEL preassemblerSelector;
+}
+
++ (id)repetitionWithSubparser:(TDParser *)p
+{
+ return [[self alloc] initWithSubparser:p];
+}
+
+- (id)init
+{
+ return [self initWithSubparser:nil];
+}
+
+- (id)initWithSubparser:(TDParser)p
+{
+ if (self = [super init])
+ self.subparser = p;
+
+ return self;
+}
+
+- (void)setPreassembler:(id)a selector:(SEL)sel
+{
+ preassembler = a;
+ preassemblerSelector = sel;
+}
+
+- (TDParser)parserNamed:(CPString)s
+{
+ if (name === s)
+ return self;
+ else
+ return [subparser parserNamed:s];
+}
+
+- (CPSet)allMatchesFor:(CPSet)inAssemblies
+{
+ if (preassembler) {
+ //NSAssert2([preassembler respondsToSelector:preassemblerSelector], @"provided preassembler %@ should respond to %s", preassembler, preassemblerSelector);
+ var values = [inAssemblies allValues],
+ length = [values count];
+
+ for (var i=0; i<length; i++)
+ [preassembler performSelector:preassemblerSelector withObject:values[a]];
+ }
+
+ //NSMutableSet *outAssemblies = [[[NSSet alloc] initWithSet:inAssemblies copyItems:YES] autorelease];
+ var outAssemblies = [inAssemblies copy],
+ s = inAssemblies;
+
+ while ([s count]) {
+ s = [subparser matchAndAssemble:s];
+ [outAssemblies unionSet:s];
+ }
+
+ return outAssemblies;
+}
+
+@end
27 TDSequence.j
@@ -0,0 +1,27 @@
+
+@import "TDCollectionParser.j"
+
+@implementation TDSequence : TDCollectionParser
+{
+}
+
++ (id)sequence
+{
+ return [[self alloc] init];
+}
+
+- (CPSet)allMatchesFor:(CPSet)inAssemblies
+{
+ var outAssemblies = inAssemblies;
+
+ for (var i=0, count = [subparsers count]; i<count; i++) {
+ outAssemblies = [subparsers[i] matchAndAssemble:outAssemblies];
+
+ if (![outAssemblies count])
+ break;
+ }
+
+ return outAssemblies;
+}
+
+@end
73 TDTerminal.j
@@ -0,0 +1,73 @@
+
+@import "TDParser.j"
+@import "TDToken.j"
+@improt "TDAssembly.j"
+
+@implementation TDTerminal : TDParser
+{
+ CPString string;
+ BOOL discardFlag;
+}
+
+- (id)init
+{
+ return [self initWithString:nil];
+}
+
+- (id)initWithString:(CPString)s
+{
+ if (self = [super init]) {
+ string = s;
+ }
+
+ return self;
+}
+
+- (CPSet)allMatchesFor:(CPSet)inAssemblies
+{
+ var outAssemblies = [CPSet set],
+ values = [inAssemblies allValues];
+
+ for (var i=0, count=[values count]; i<count; i++)
+ {
+ var a = values[i],
+ b = [self matchOneAssembly:a];
+
+ if (b)
+ [outAssemblies addObject:b]
+ }
+
+ return outAssemblies;
+}
+
+- (TDAssembly)matchOneAssembly:(TDAssembly)inAssembly
+{
+ if (![inAssembly hasMore])
+ return nil;
+
+ var outAssembly = nil;
+
+ if ([self qualifies:[inAssembly peek]]) {
+ outAssembly = [inAssembly copy];
+
+ var obj = [outAssembly next];
+ if (!discardFlag)
+ [outAssembly push:obj];
+ }
+
+ return outAssembly;
+}
+
+- (BOOL)qualifies:(id)obj
+{
+ //NSAssert1(0, @"-[TDTerminal %s] must be overriden", _cmd);
+ return NO;
+}
+
+- (TDTerminal)discard
+{
+ discardFlag = YES;
+ return self;
+}
+
+@end
165 TDToken.j
@@ -0,0 +1,165 @@
+
+//TDTokenType
+
+TDTokenTypeEOF = 0;
+TDTokenTypeNumber = 1;
+TDTokenTypeQuotedString = 2;
+TDTokenTypeSymbol = 3;
+TDTokenTypeWord = 4;
+TDTokenTypeWhitespace = 5;
+TDTokenTypeComment = 6;
+
+@implementation TDToken : CPObject
+{
+ float floatValue;
+ CPString stringValue;
+ TDTokenType tokenType;
+
+ BOOL number;
+ BOOL quotedString;
+ BOOL symbol;
+ BOOL word;
+ BOOL whitespace;
+ BOOL comment;
+
+ id value;
+}
+
++ (TDToken)EOFToken
+{
+ return [TDTokenEOF instance];
+}
+
++ (id)tokenWithTokenType:(TDTokenType)t stringValue:(CPString)s floatValue:(float)n
+{
+ return [[self alloc] initWithTokenType:t stringValue:s floatValue:n];
+}
+
+// designated initializer
+- (id)initWithTokenType:(TDTokenType)t stringValue:(NSString *)s floatValue:(CGFloat)n
+{
+ if (self = [super init]) {
+ tokenType = t;
+ stringValue = s;
+ floatValue = n;
+
+ number = (TDTokenTypeNumber == t);
+ quotedString = (TDTokenTypeQuotedString == t);
+ symbol = (TDTokenTypeSymbol == t);
+ word = (TDTokenTypeWord == t);
+ whitespace = (TDTokenTypeWhitespace == t);
+ comment = (TDTokenTypeComment == t);
+ }
+
+ return self;
+}
+
+- (unsigned)hash
+{
+ return [stringValue hash];
+}
+
+
+- (BOOL)isEqual:(id)rhv
+{
+ return [self isEqual:rhv ignoringCase:NO];
+}
+
+
+- (BOOL)isEqualIgnoringCase:(id)rhv
+{
+ return [self isEqual:rhv ignoringCase:YES];
+}
+
+- (BOOL)isEqual:(id)rhv ignoringCase:(BOOL)ignoringCase
+{
+ if (![rhv isMemberOfClass:[TDToken class]])
+ return NO;
+
+ var tok = rhv;
+ if (tokenType != tok.tokenType)
+ return NO;
+
+ if (number)
+ return floatValue == tok.floatValue;
+ else
+ {
+ if (ignoringCase)
+ return CPOrderedSame == [stringValue caseInsensitiveCompare:tok.stringValue];
+ else
+ return stringValue === tok.stringValue;
+ }
+}
+
+- (id)value
+{
+ if (!value)
+ {
+ if (number)
+ value = floatValue;
+ else
+ value = stringValue;
+ }
+
+ return value;
+}
+
+- (CPString)debugDescription
+{
+ /*
+ var typeString = nil;
+ if (self.isNumber) {
+ typeString = @"Number";
+ } else if (self.isQuotedString) {
+ typeString = @"Quoted String";
+ } else if (self.isSymbol) {
+ typeString = @"Symbol";
+ } else if (self.isWord) {
+ typeString = @"Word";
+ } else if (self.isWhitespace) {
+ typeString = @"Whitespace";
+ } else if (self.isComment) {
+ typeString = @"Comment";
+ }
+ return [NSString stringWithFormat:@"<%@ %C%@%C>", typeString, 0x00AB, self.value, 0x00BB];
+ */
+ return [self description];
+}
+
+- (CPString)description
+{
+ return stringValue;
+}
+
+@end
+
+EOFToken = nil;
+
+@implementation TDTokenEOF : TDToken
+{
+}
+
++ (TDTokenEOF)instance
+{
+ if (!EOFToken)
+ EOFToken = [[self alloc] init];
+
+ return EOFToken;
+}
+
+- (id)copy
+{
+ return self;
+}
+
+- (CPString)description
+{
+ return [CPString stringWithFormat:@"<TDTokenEOF %p>", self];
+}
+
+- (CPString)debugDescription
+{
+ return [self description];
+}
+
+@end
168 TDTokenAssembly.j
@@ -0,0 +1,168 @@
+
+@import "TDAssembly.j"
+@import "TDTokenizer.j"
+@import "TDToken.j"
+
+@implementation TDTokenAssembly : TDAssembly
+{
+ TDTokenizer tokenizer;
+ CPArray tokens;
+ BOOL preservesWhitespaceTokens;
+}
+
++ (id)assemblyWithTokenizer:(TDTokenizer)t
+{
+ return [[self alloc] initWithTokenzier:t];
+}
+
+- (id)initWithTokenzier:(TDTokenizer)t
+{
+ return [self initWithString:t.string tokenzier:t tokenArray:nil];
+}
+
++ (id)assemblyWithTokenArray:(CPArray)a
+{
+ return [[self alloc] initWithTokenArray:a];
+}
+
+- (id)initWithTokenArray:(CPArray)a
+{
+ return [self initWithString:[a componentsJoinedByString:@""] tokenzier:nil tokenArray:a];
+}
+
+- (id)initWithString:(CPString)s
+{
+ return [self initWithTokenzier:[[TDTokenizer alloc] initWithString:s]];
+}
+
+// designated initializer. this method is private and should not be called from other classes
+- (id)initWithString:(CPString)s tokenzier:(TDTokenizer)t tokenArray:(CPArray)a
+{
+ if (self = [super initWithString:s]) {
+ if (t)
+ tokenizer = t;
+ else
+ tokens = a;
+ }
+
+ return self;
+}
+
+- (id)copy
+{
+ var a = [super copy];
+
+ a.tokens = [[self tokens] copy];
+ a.preservesWhitespaceTokens = preservesWhitespaceTokens;
+
+ return a;
+}
+
+- (CPArray)tokens
+{
+ if (!tokens)
+ [self tokenize];
+
+ return tokens;
+}
+
+- (id)peek
+{
+ var tok = nil;
+
+ while (1)
+ {
+ if (index >= [[self tokens] count]) {
+ tok = nil;
+ break;
+ }
+
+ tok = [self tokens][index];
+ if (!preservesWhitespaceTokens)
+ break;
+
+ if (TDTokenTypeWhitespace == tok.tokenType) {
+ [self push:tok];
+ index++;
+ }
+ else
+ break;
+ }
+
+ return tok;
+}
+
+- (id)next
+{
+ var tok = [self peek];
+
+ if (tok)
+ index++;
+
+ return tok;
+}
+
+- (BOOL)hasMore
+{
+ return (index < [[self tokens] count]);
+}
+
+- (unsigned)length
+{
+ return [[self tokens] count];
+}
+
+- (unsigned)objectsConsumed
+{
+ return index;
+}
+
+- (unsigned)objectsRemaining
+{
+ return ([[self tokens] count] - index);
+}
+
+- (CPString)consumedObjectsJoinedByString:(CPString)delimiter
+{
+ return [self objectsFrom:0 to:[self objectsConsumed] separatedBy:delimiter];
+}
+
+- (CPString)remainingObjectsJoinedByString:(CPString)delimiter
+{
+ return [self objectsFrom:[self objectsConsumed] to:[self length] separatedBy:delimiter];
+}
+
+- (void)tokenize
+{
+ if (!tokenizer)
+ return;
+
+ var a = [],
+ eof = [TDToken EOFToken],
+ tok = nil;
+
+ while ((tok = [tokenizer nextToken]) != eof) {
+ [a addObject:tok];
+ }
+
+ tokens = a;
+}
+
+
+- (CPString)objectsFrom:(unsigned)start to:(unsigned)end separatedBy:(CPString)delimiter
+{
+ var s = "",
+ i = start;
+
+ for ( ; i < end; i++) {
+ var tok = [self tokens][i];
+ s += [tok stringValue];
+
+ if (end - 1 != i)
+ s += delimiter;
+ }
+
+ return s;
+}
+
+@end
168 TDTokenizer.j
@@ -0,0 +1,168 @@
+
+@import "TDParseKit.j"
+
+@implementation TDTokenizer : CPObject
+{
+ CPString string;
+ TDReader reader;
+
+ CPArray tokenizerStates;
+
+ TDNumberState numberState;
+ TDQuoteState quoteState;
+ TDCommentState commentState;
+ TDSymbolState symbolState;
+ TDWhitespaceState whitespaceState;
+ TDWordState wordState;
+}
+
++ (id)tokenizer
+{
+ return [self tokenizerWithString:nil];
+}
+
++ (id)tokenizerWithString:(CPString)s
+{
+ return [[self alloc] initWithString:s];
+}
+
+- (id)init
+{
+ return [self initWithString:nil];
+}
+
+- (id)initWithString:(CPString)s
+{
+ if (self = [super init])
+ {
+ string = s;
+ [self setReader:[[TDReader alloc] init]];
+
+ numberState = [[TDNumberState alloc] init];
+ quoteState = [[TDQuoteState alloc] init];
+ commentState = [[TDCommentState alloc] init];
+ symbolState = [[TDSymbolState alloc] init];
+ whitespaceState = [[TDWhitespaceState alloc] init];
+ wordState = [[TDWordState alloc] init];
+
+ [symbolState add:@"<="];
+ [symbolState add:@">="];
+ [symbolState add:@"!="];
+ [symbolState add:@"=="];
+
+ [commentState addSingleLineStartSymbol:@"//"];
+ [commentState addMultiLineStartSymbol:@"/*" endSymbol:@"*/"];
+
+ tokenizerStates = [[NSMutableArray alloc] initWithCapacity:256];
+
+ [self addTokenizerState:whitespaceState from: 0 to: ' ']; // From: 0 to: 32 From:0x00 to:0x20
+ [self addTokenizerState:symbolState from: 33 to: 33];
+ [self addTokenizerState:quoteState from: '"' to: '"']; // From: 34 to: 34 From:0x22 to:0x22
+ [self addTokenizerState:symbolState from: 35 to: 38];
+ [self addTokenizerState:quoteState from:'\'' to:'\'']; // From: 39 to: 39 From:0x27 to:0x27
+ [self addTokenizerState:symbolState from: 40 to: 42];
+ [self addTokenizerState:symbolState from: '+' to: '+']; // From: 43 to: 43 From:0x2B to:0x2B
+ [self addTokenizerState:symbolState from: 44 to: 44];
+ [self addTokenizerState:numberState from: '-' to: '-']; // From: 45 to: 45 From:0x2D to:0x2D
+ [self addTokenizerState:numberState from: '.' to: '.']; // From: 46 to: 46 From:0x2E to:0x2E
+ [self addTokenizerState:commentState from: '/' to: '/']; // From: 47 to: 47 From:0x2F to:0x2F
+ [self addTokenizerState:numberState from: '0' to: '9']; // From: 48 to: 57 From:0x30 to:0x39
+ [self addTokenizerState:symbolState from: 58 to: 64];
+ [self addTokenizerState:wordState from: 'A' to: 'Z']; // From: 65 to: 90 From:0x41 to:0x5A
+ [self addTokenizerState:symbolState from: 91 to: 96];
+ [self addTokenizerState:wordState from: 'a' to: 'z']; // From: 97 to:122 From:0x61 to:0x7A
+ [self addTokenizerState:symbolState from: 123 to: 191];
+ [self addTokenizerState:wordState from:0xC0 to:0xFF]; // From:192 to:255 From:0xC0 to:0xFF
+ }
+
+ return self;
+}
+
+- (TDToken)nextToken
+{
+ var c = [reader read],
+ result = nil;
+
+ if (-1 === c)
+ result = [TDToken EOFToken];
+ else
+ {
+ var state = [self tokenizerStateFor:c];
+
+ if (state)
+ result = [state nextTokenFromReader:reader startingWith:c tokenizer:self];
+ else
+ result = [TDToken EOFToken];
+ }
+
+ return result;
+}
+
+- (void)addTokenizerState:(TDTokenizerState)state from:(unsigned)start to:(unsigned)end
+{
+ for (var i=start; i <= end; i++) {
+ [tokenizerStates addObject:state];
+ //addObject(tokenizerStates, @selector(addObject:), state);
+ }
+}
+
+- (void)setTokenizerState:(TDTokenizerState)state from:(unsigned)start to:(unsigned)end
+{
+ for (var i = start; i <= end; i++) {
+ [tokenizerStates replaceObjectAtIndex:i withObject:state];
+ //relaceObject(tokenizerStates, @selector(replaceObjectAtIndex:withObject:), i, state);
+ }
+}
+
+- (TDReader)reader
+{
+ return reader;
+}
+
+- (void)setReader:(TDReader)r
+{
+ if (reader != r) {
+ reader = r
+ reader.string = string;
+ }
+}
+
+- (CPString)string
+{
+ return string;
+}
+
+- (void)setString:(CPString)s
+{
+ string = s;
+ reader.string = string;
+}
+
+- (TDTokenizerState)tokenizerStateFor:(unsigned)c
+{
+ if (c < 0 || c > 255) {
+ if (c >= 0x19E0 && c <= 0x19FF) { // khmer symbols
+ return symbolState;
+ } else if (c >= 0x2000 && c <= 0x2BFF) { // various symbols
+ return symbolState;
+ } else if (c >= 0x2E00 && c <= 0x2E7F) { // supplemental punctuation
+ return symbolState;
+ } else if (c >= 0x3000 && c <= 0x303F) { // cjk symbols & punctuation
+ return symbolState;
+ } else if (c >= 0x3200 && c <= 0x33FF) { // enclosed cjk letters and months, cjk compatibility
+ return symbolState;
+ } else if (c >= 0x4DC0 && c <= 0x4DFF) { // yijing hexagram symbols
+ return symbolState;
+ } else if (c >= 0xFE30 && c <= 0xFE6F) { // cjk compatibility forms, small form variants
+ return symbolState;
+ } else if (c >= 0xFF00 && c <= 0xFFFF) { // hiragana & katakana halfwitdh & fullwidth forms, Specials
+ return symbolState;
+ } else {
+ return wordState;
+ }
+ }
+
+ return tokenizerStates[c];
+}
+
+@end
68 TDTrack.j
@@ -0,0 +1,68 @@
+
+@import "TDSequence.j"
+@import "TDAssembly.j"
+//@import "TDTrackException.j"
+
+@implementation TDTrack : TDSequence
+{
+}
+
++ (id)track
+{
+ return [[self alloc] init];
+}
+
+- (CPSet)allMatchesFor:(CPSet)inAssemblies
+{
+ var inTrack = NO,
+ lastAssemblies = inAssemblies,
+ outAssemblies = inAssemblies;
+
+ for (var i=0, count=[subparsers count]; i<count; i++)
+ {
+ var p = subparsers[i];
+
+ outAssemblies = [i matchAndAssemble:outAssemblies];
+
+ if (![outAssemblies count])
+ {
+ if (inTrack)
+ [self throwTrackExceptionWithPreviousState:lastAssemblies parser:p];
+
+ break;
+ }
+
+ inTrack = YES;
+ lastAssemblies = outAssemblies;
+ }
+
+ return outAssemblies;
+}
+
+- (void)throwTrackExceptionWithPreviousState:(NSSet *)inAssemblies parser:(TDParser *)p
+{
+ [CPException raise:"TDTrackException" reason:"TDTrack"];
+ /*
+ TDAssembly *best = [self best:inAssemblies];
+
+ NSString *after = [best consumedObjectsJoinedByString:@" "];
+ if (!after.length) {
+ after = @"-nothing-";
+ }
+
+ NSString *expected = [p description];
+
+ id next = [best peek];
+ NSString *found = next ? [next description] : @"-nothing-";
+
+ NSString *reason = [NSString stringWithFormat:@"\n\nAfter : %@\nExpected : %@\nFound : %@\n\n", after, expected, found];
+ NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ after, @"after",
+ expected, @"expected",
+ found, @"found",
+ nil];
+ [[TDTrackException exceptionWithName:TDTrackExceptionName reason:reason userInfo:userInfo] raise];
+ */
+}
+
+@end
Please sign in to comment.
Something went wrong with that request. Please try again.