Skip to content

Commit

Permalink
improved JSON parser
Browse files Browse the repository at this point in the history
Signed-off-by: Rifat Nabi <to.rifat@gmail.com>
  • Loading branch information
torifat committed Jun 28, 2012
1 parent 9c1acf0 commit 1576baa
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2,817 deletions.
3 changes: 2 additions & 1 deletion AvroParser.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
NSString* _vowel; NSString* _vowel;
NSString* _consonant; NSString* _consonant;
NSString* _casesensitive; NSString* _casesensitive;
NSDictionary* _patterns; NSArray* _patterns;
int _maxPatternLength;
} }


+ (void)allocateSharedInstance; + (void)allocateSharedInstance;
Expand Down
205 changes: 110 additions & 95 deletions AvroParser.m
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ - (id)init {
_consonant = [jsonArray objectForKey:@"consonant"]; _consonant = [jsonArray objectForKey:@"consonant"];
_casesensitive = [jsonArray objectForKey:@"casesensitive"]; _casesensitive = [jsonArray objectForKey:@"casesensitive"];
_patterns = [jsonArray objectForKey:@"patterns"]; _patterns = [jsonArray objectForKey:@"patterns"];
_maxPatternLength = [[[_patterns objectAtIndex:0] objectForKey:@"find"] length];
} }


} else { } else {
Expand Down Expand Up @@ -87,113 +88,126 @@ - (NSString*)parse:(NSString *)string {
int start = cur, end; int start = cur, end;
BOOL matched = FALSE; BOOL matched = FALSE;


for(NSDictionary *pattern in _patterns) { int chunkLen;
NSString* find = [pattern objectForKey:@"find"]; for(chunkLen = _maxPatternLength; chunkLen > 0; --chunkLen) {
int findLen = [find length]; end = start + chunkLen;
end = cur + findLen; if(end <= len) {
int diff = (end - start); NSString* chunk = [fixed substringWithRange:NSMakeRange(start, chunkLen)];
if(end <= len && diff == findLen) {
NSString* chunk = [fixed substringWithRange:NSMakeRange(start, diff)]; // Binary Search
if(chunk && [chunk length] && [chunk isEqualToString:find]) { int left = 0, right = [_patterns count] - 1, mid;
NSArray* rules = [pattern objectForKey:@"rules"]; while(right >= left) {
for(NSDictionary* rule in rules) { mid = (right + left) / 2;

NSDictionary* pattern = [_patterns objectAtIndex:mid];
BOOL replace = TRUE; NSString* find = [pattern objectForKey:@"find"];
int chk = 0; if([find isEqualToString:chunk]) {
NSArray* matches = [rule objectForKey:@"matches"]; NSArray* rules = [pattern objectForKey:@"rules"];
for(NSDictionary* match in matches) { for(NSDictionary* rule in rules) {
NSString* value = [match objectForKey:@"value"];
NSString* type = [match objectForKey:@"type"];
NSString* scope = [match objectForKey:@"scope"];
BOOL isNegative = [[match objectForKey:@"negative"] boolValue];

if([type isEqualToString:@"suffix"]) {
chk = end;
}
// Prefix
else {
chk = start - 1;
}


// Beginning BOOL replace = TRUE;
if([scope isEqualToString:@"punctuation"]) { int chk = 0;
if( NSArray* matches = [rule objectForKey:@"matches"];
! ( for(NSDictionary* match in matches) {
(chk < 0 && [type isEqualToString:@"prefix"]) || NSString* value = [match objectForKey:@"value"];
(chk >= len && [type isEqualToString:@"suffix"]) || NSString* type = [match objectForKey:@"type"];
[self isPunctuation:[fixed characterAtIndex:chk]] NSString* scope = [match objectForKey:@"scope"];
) ^ isNegative BOOL isNegative = [[match objectForKey:@"negative"] boolValue];
) {
replace = FALSE;
break;
}
}
// Vowel
else if([scope isEqualToString:@"vowel"]) {
if(
! (
(
(chk >= 0 && [type isEqualToString:@"prefix"]) ||
(chk < len && [type isEqualToString:@"suffix"])
) &&
[self isVowel:[fixed characterAtIndex:chk]]
) ^ isNegative
) {
replace = FALSE;
break;
}
}
// Consonant
else if([scope isEqualToString:@"consonant"]) {
if(
! (
(
(chk >= 0 && [type isEqualToString:@"prefix"]) ||
(chk < len && [type isEqualToString:@"suffix"])
) &&
[self isConsonant:[fixed characterAtIndex:chk]]
) ^ isNegative
) {
replace = FALSE;
break;
}
}
// Exact
else if([scope isEqualToString:@"exact"]) {
int s, e;
if([type isEqualToString:@"suffix"]) { if([type isEqualToString:@"suffix"]) {
s = end; chk = end;
e = end + [value length];
} }
// Prefix // Prefix
else { else {
s = start - [value length]; chk = start - 1;
e = start;
} }
if(![self isExact:value heystack:fixed start:s end:e not:isNegative]) {
replace = FALSE; // Beginning
break; if([scope isEqualToString:@"punctuation"]) {
if(
! (
(chk < 0 && [type isEqualToString:@"prefix"]) ||
(chk >= len && [type isEqualToString:@"suffix"]) ||
[self isPunctuation:[fixed characterAtIndex:chk]]
) ^ isNegative
) {
replace = FALSE;
break;
}
} }
// Vowel
else if([scope isEqualToString:@"vowel"]) {
if(
! (
(
(chk >= 0 && [type isEqualToString:@"prefix"]) ||
(chk < len && [type isEqualToString:@"suffix"])
) &&
[self isVowel:[fixed characterAtIndex:chk]]
) ^ isNegative
) {
replace = FALSE;
break;
}
}
// Consonant
else if([scope isEqualToString:@"consonant"]) {
if(
! (
(
(chk >= 0 && [type isEqualToString:@"prefix"]) ||
(chk < len && [type isEqualToString:@"suffix"])
) &&
[self isConsonant:[fixed characterAtIndex:chk]]
) ^ isNegative
) {
replace = FALSE;
break;
}
}
// Exact
else if([scope isEqualToString:@"exact"]) {
int s, e;
if([type isEqualToString:@"suffix"]) {
s = end;
e = end + [value length];
}
// Prefix
else {
s = start - [value length];
e = start;
}
if(![self isExact:value heystack:fixed start:s end:e not:isNegative]) {
replace = FALSE;
break;
}
}
}

if(replace) {
[output appendString:[rule objectForKey:@"replace"]];
cur = end - 1;
matched = TRUE;
break;
} }

} }


if(replace) { if(matched == TRUE) break;
[output appendString:[rule objectForKey:@"replace"]];
cur = end - 1;
matched = TRUE;
break;
}


// Default
[output appendString:[pattern objectForKey:@"replace"]];
cur = end - 1;
matched = TRUE;
break;
}
else if ([find length] > [chunk length] ||
([find length] == [chunk length] && [find compare:chunk] == NSOrderedAscending)) {
left = mid + 1;
} else {
right = mid - 1;
} }

if(matched == true) break;

// Default
[output appendString:[pattern objectForKey:@"replace"]];
cur = end - 1;
matched = TRUE;
break;
} }
if(matched == TRUE) break;
} }
} }


Expand Down Expand Up @@ -254,7 +268,8 @@ - (BOOL)isCaseSensitive:(unichar)c {
- (BOOL)isExact:(NSString*) needle heystack:(NSString*)heystack start:(int)start end:(int)end not:(BOOL)not { - (BOOL)isExact:(NSString*) needle heystack:(NSString*)heystack start:(int)start end:(int)end not:(BOOL)not {
// NSLog(@"Cut: %@", [heystack substringWithRange:NSMakeRange(start, end)]); // NSLog(@"Cut: %@", [heystack substringWithRange:NSMakeRange(start, end)]);
int len = end - start; int len = end - start;
return ((start >=0 && end < [heystack length] && [[heystack substringWithRange:NSMakeRange(start, len)] isEqualToString:needle]) ^ not); return ((start >= 0 && end < [heystack length]
&& [[heystack substringWithRange:NSMakeRange(start, len)] isEqualToString:needle]) ^ not);
} }


- (unichar) smallCap:(unichar) letter { - (unichar) smallCap:(unichar) letter {
Expand Down
Loading

0 comments on commit 1576baa

Please sign in to comment.