Skip to content

Commit

Permalink
Added support for LALR(1) parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
beelsebob committed Apr 4, 2011
1 parent 9b919a0 commit 7d6682c
Show file tree
Hide file tree
Showing 9 changed files with 482 additions and 102 deletions.
16 changes: 12 additions & 4 deletions CoreParse.xcodeproj/project.pbxproj
Expand Up @@ -71,6 +71,8 @@
1F530B8813216A1A00F52EB5 /* CPSyntaxTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F530B8613216A1A00F52EB5 /* CPSyntaxTree.m */; };
1F530B911322814000F52EB5 /* CPRule.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F530B8F1322813E00F52EB5 /* CPRule.h */; settings = {ATTRIBUTES = (Public, ); }; };
1F530B921322814000F52EB5 /* CPRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F530B901322813F00F52EB5 /* CPRule.m */; };
1F6D44901348CC9500E982C7 /* CPLALR1Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F6D448E1348CC9500E982C7 /* CPLALR1Parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
1F6D44911348CC9600E982C7 /* CPLALR1Parser.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F6D448F1348CC9500E982C7 /* CPLALR1Parser.m */; };
1FB3EB24132BA02C00ACC453 /* CPTestEvaluatorDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FB3EB22132BA02C00ACC453 /* CPTestEvaluatorDelegate.h */; };
1FB3EB25132BA02C00ACC453 /* CPTestEvaluatorDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FB3EB23132BA02C00ACC453 /* CPTestEvaluatorDelegate.m */; };
1FB3EB2C132BB2F200ACC453 /* CPLR1Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FB3EB2A132BB2E600ACC453 /* CPLR1Parser.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -167,6 +169,8 @@
1F530B8613216A1A00F52EB5 /* CPSyntaxTree.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPSyntaxTree.m; sourceTree = "<group>"; };
1F530B8F1322813E00F52EB5 /* CPRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPRule.h; sourceTree = "<group>"; };
1F530B901322813F00F52EB5 /* CPRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPRule.m; sourceTree = "<group>"; };
1F6D448E1348CC9500E982C7 /* CPLALR1Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPLALR1Parser.h; sourceTree = "<group>"; };
1F6D448F1348CC9500E982C7 /* CPLALR1Parser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPLALR1Parser.m; sourceTree = "<group>"; };
1FB3EB22132BA02C00ACC453 /* CPTestEvaluatorDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPTestEvaluatorDelegate.h; sourceTree = "<group>"; };
1FB3EB23132BA02C00ACC453 /* CPTestEvaluatorDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPTestEvaluatorDelegate.m; sourceTree = "<group>"; };
1FB3EB2A132BB2E600ACC453 /* CPLR1Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPLR1Parser.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -316,17 +320,19 @@
1F3881EC1322B669000C8876 /* CPShiftReduceActionTable.m */,
1F3881EF1322B69E000C8876 /* CPShiftReduceGotoTable.h */,
1F3881F01322B6A0000C8876 /* CPShiftReduceGotoTable.m */,
1F3882071323F75E000C8876 /* CPItem.h */,
1F3882081323F75F000C8876 /* CPItem.m */,
1FB3EB2E132BB30300ACC453 /* CPLR1Item.h */,
1FB3EB2F132BB30A00ACC453 /* CPLR1Item.m */,
1F3881DA1322ACE7000C8876 /* CPShiftReduceParser.h */,
1F3882031323DDD6000C8876 /* CPShiftReduceParserProtectedMethods.h */,
1F3881DB1322ACE7000C8876 /* CPShiftReduceParser.m */,
1F3881FF1323DB49000C8876 /* CPSLRParser.h */,
1F3882001323DB49000C8876 /* CPSLRParser.m */,
1F3882071323F75E000C8876 /* CPItem.h */,
1F3882081323F75F000C8876 /* CPItem.m */,
1FB3EB2A132BB2E600ACC453 /* CPLR1Parser.h */,
1FB3EB2B132BB2ED00ACC453 /* CPLR1Parser.m */,
1FB3EB2E132BB30300ACC453 /* CPLR1Item.h */,
1FB3EB2F132BB30A00ACC453 /* CPLR1Item.m */,
1F6D448E1348CC9500E982C7 /* CPLALR1Parser.h */,
1F6D448F1348CC9500E982C7 /* CPLALR1Parser.m */,
);
path = CPShiftReduceParsers;
sourceTree = "<group>";
Expand Down Expand Up @@ -440,6 +446,7 @@
1F530B911322814000F52EB5 /* CPRule.h in Headers */,
1F3882011323DB4A000C8876 /* CPSLRParser.h in Headers */,
1FB3EB2C132BB2F200ACC453 /* CPLR1Parser.h in Headers */,
1F6D44901348CC9500E982C7 /* CPLALR1Parser.h in Headers */,
1FB3EB3A132D096900ACC453 /* CPGrammarSymbol.h in Headers */,
1F45A2E413422E1300092D78 /* CPJSONParser.h in Headers */,
1F3881DC1322ACE7000C8876 /* CPShiftReduceParser.h in Headers */,
Expand Down Expand Up @@ -597,6 +604,7 @@
1FB81323132FEDAF0095982D /* CPTestWhiteSpaceIgnoringDelegate.m in Sources */,
1FB81327132FF16E0095982D /* CPTestMapCSSTokenisingDelegate.m in Sources */,
1F45A2E513422E1300092D78 /* CPJSONParser.m in Sources */,
1F6D44911348CC9600E982C7 /* CPLALR1Parser.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
1 change: 1 addition & 0 deletions CoreParse/CoreParse.h
Expand Up @@ -33,5 +33,6 @@
#import "CPParser.h"
#import "CPSLRParser.h"
#import "CPLR1Parser.h"
#import "CPLALR1Parser.h"

#import "CPJSONParser.h"
7 changes: 6 additions & 1 deletion CoreParse/Grammar/CPGrammar.h
Expand Up @@ -33,10 +33,15 @@
- (NSUInteger)indexOfRule:(CPRule *)rule;

- (NSSet *)lr0Closure:(NSSet *)i;
- (NSSet *)lr0GotoKernelWithItems:(NSSet *)i symbol:(NSObject *)symbol;
- (NSSet *)lr0GotoKernelWithItems:(NSSet *)i symbol:(CPGrammarSymbol *)symbol;
- (NSArray *)lr0Kernels;

- (NSSet *)lr1Closure:(NSSet *)i;
- (NSSet *)lr1GotoKernelWithItems:(NSSet *)i symbol:(CPGrammarSymbol *)symbol;

- (NSSet *)follow:(NSString *)name;
- (NSSet *)first:(NSArray *)obj;

- (NSString *)uniqueSymbolNameBasedOnName:(NSString *)name;

@end
111 changes: 96 additions & 15 deletions CoreParse/Grammar/CPGrammar.m
Expand Up @@ -22,6 +22,7 @@
#import "CPNumberToken.h"

#import "CPItem.h"
#import "CPLR1Item.h"

#import "NSSetFunctional.h"

Expand Down Expand Up @@ -119,7 +120,8 @@ @interface CPGrammar ()

@property (readwrite,copy) NSArray *rules;

- (NSSet *)firstSymbol:(NSObject *)obj;
- (NSSet *)allSymbolNames;
- (NSSet *)firstSymbol:(CPGrammarSymbol *)obj;

@end

Expand Down Expand Up @@ -252,6 +254,34 @@ - (NSSet *)allRules
return rs;
}

- (NSSet *)allSymbolNames
{
NSMutableSet *symbols = [NSMutableSet set];

for (CPRule *rule in [self allRules])
{
[symbols addObject:[rule name]];
for (CPGrammarSymbol *sym in [rule rightHandSideElements])
{
[symbols addObject:[sym name]];
}
}

return symbols;
}

- (NSString *)uniqueSymbolNameBasedOnName:(NSString *)name
{
NSString *testName = [[name copy] autorelease];
NSSet *allSymbols = [self allSymbolNames];
while ([allSymbols containsObject:testName])
{
testName = [NSString stringWithFormat:@"_%@", testName];
}

return testName;
}

- (NSArray *)orderedRules
{
return [[[self allRules] allObjects] sortedArrayUsingComparator:^ NSComparisonResult (CPRule *r1, CPRule *r2)
Expand Down Expand Up @@ -340,21 +370,21 @@ - (NSSet *)lr0Closure:(NSSet *)i
return [j autorelease];
}

- (NSSet *)lr0GotoKernelWithItems:(NSSet *)i symbol:(NSObject *)symbol
- (NSSet *)lr0GotoKernelWithItems:(NSSet *)i symbol:(CPGrammarSymbol *)symbol
{
return [self lr0Closure:[[i objectsPassingTest:^ BOOL (CPItem *item, BOOL *stop)
{
return [symbol isEqual:[item nextSymbol]];
}]
map:^ id (CPItem *item)
{
return [item itemByMovingDotRight];
}]];
return [[i objectsPassingTest:^ BOOL (CPItem *item, BOOL *stop)
{
return [symbol isEqual:[item nextSymbol]];
}]
map:^ id (CPItem *item)
{
return [item itemByMovingDotRight];
}];
}

- (NSArray *)lr0Kernels
{
CPRule *startRule = [[self rulesForNonTerminalWithName:@"s'"] objectAtIndex:0];
CPRule *startRule = [[self rulesForNonTerminalWithName:[self start]] objectAtIndex:0];
NSSet *initialKernel = [NSSet setWithObject:[CPItem itemWithRule:startRule position:0]];
NSMutableArray *c = [NSMutableArray arrayWithObject:initialKernel];
NSMutableArray *processingQueue = [NSMutableArray arrayWithObject:initialKernel];
Expand All @@ -381,6 +411,56 @@ - (NSArray *)lr0Kernels
return c;
}

- (NSSet *)lr1Closure:(NSSet *)i
{
NSMutableSet *j = [i mutableCopy];
NSMutableArray *processingQueue = [[j allObjects] mutableCopy];

while ([processingQueue count] > 0)
{
CPLR1Item *item = (CPLR1Item *)[processingQueue objectAtIndex:0];
NSArray *followingSymbols = [item followingSymbols];
CPGrammarSymbol *nextSymbol = [followingSymbols count] > 0 ? [followingSymbols objectAtIndex:0] : nil;
if (![nextSymbol isTerminal])
{
NSArray *rs = [self rulesForNonTerminalWithName:[(CPGrammarSymbol *)nextSymbol name]];
for (CPRule *r in rs)
{
NSArray *afterNext = [followingSymbols subarrayWithRange:NSMakeRange(1, [followingSymbols count] - 1)];
NSArray *afterNextWithTerminal = [afterNext arrayByAddingObject:[item terminal]];
NSSet *firstAfterNext = [self first:afterNextWithTerminal];
for (NSString *o in firstAfterNext)
{
CPLR1Item *newItem = [CPLR1Item lr1ItemWithRule:r position:0 terminal:[CPGrammarSymbol terminalWithName:o]];
if (![j containsObject:newItem])
{
[processingQueue addObject:newItem];
[j addObject:newItem];
}
}
}
}

[processingQueue removeObjectAtIndex:0];
}

[processingQueue release];

return [j autorelease];
}

- (NSSet *)lr1GotoKernelWithItems:(NSSet *)i symbol:(CPGrammarSymbol *)symbol
{
return [[i objectsPassingTest:^ BOOL (CPItem *item, BOOL *stop)
{
return [symbol isEqual:[item nextSymbol]];
}]
map:^ id (CPItem *item)
{
return [item itemByMovingDotRight];
}];
}

- (NSSet *)follow:(NSString *)name
{
NSSet *follows = [followCache objectForKey:name];
Expand Down Expand Up @@ -424,7 +504,7 @@ - (NSSet *)first:(NSArray *)symbols
{
NSMutableSet *f = [NSMutableSet set];

for (NSObject *symbol in symbols)
for (CPGrammarSymbol *symbol in symbols)
{
NSSet *f1 = [self firstSymbol:symbol];
[f unionSet:f1];
Expand All @@ -439,14 +519,15 @@ - (NSSet *)first:(NSArray *)symbols

- (NSSet *)firstSymbol:(CPGrammarSymbol *)sym
{
if ([sym isTerminal])
NSString *name = [sym name];
if ([sym isTerminal] && nil != name)
{
return [NSSet setWithObject:[sym name]];
return [NSSet setWithObject:name];
}
else
{
NSMutableSet *f = [NSMutableSet set];
NSArray *rs = [self rulesForNonTerminalWithName:[sym name]];
NSArray *rs = [self rulesForNonTerminalWithName:name];
BOOL containsEmptyRightHandSide = NO;
for (CPRule *rule in rs)
{
Expand Down
16 changes: 16 additions & 0 deletions CoreParse/Parsers/CPShiftReduceParsers/CPLALR1Parser.h
@@ -0,0 +1,16 @@
//
// CPLALR1Parser.h
// CoreParse
//
// Created by Tom Davie on 03/04/2011.
// Copyright 2011 In The Beginning... All rights reserved.
//

#import <Foundation/Foundation.h>

#import "CPLR1Parser.h"

@interface CPLALR1Parser : CPShiftReduceParser
{}

@end

0 comments on commit 7d6682c

Please sign in to comment.