Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions PEGKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

/* Begin PBXBuildFile section */
3D0466A918E1D9770022A1BC /* OCMock.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D37214CA18DF3B0100525058 /* OCMock.framework */; };
40CA4045198C3E8B0094DF1F /* PGCLI.m in Sources */ = {isa = PBXBuildFile; fileRef = 40CA4044198C3E8B0094DF1F /* PGCLI.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
40CA4048198C54AB0094DF1F /* PGGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 40CA4047198C54AB0094DF1F /* PGGenerator.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
D306298218E1ED5D00EF745E /* TDTestScaffold.m in Sources */ = {isa = PBXBuildFile; fileRef = D306298118E1ED5D00EF745E /* TDTestScaffold.m */; };
D3083AB61705F05C00DA6F95 /* elementsAssign.grammar in Resources */ = {isa = PBXBuildFile; fileRef = D3083AB51705F05C00DA6F95 /* elementsAssign.grammar */; };
D3083AB91705F09B00DA6F95 /* ElementAssignParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = D3083AB81705F09B00DA6F95 /* ElementAssignParserTest.m */; };
Expand Down Expand Up @@ -478,6 +480,10 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
40CA4044198C3E8B0094DF1F /* PGCLI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PGCLI.m; sourceTree = "<group>"; };
40CA4046198C3F4C0094DF1F /* PGCLI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PGCLI.h; sourceTree = "<group>"; };
40CA4047198C54AB0094DF1F /* PGGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PGGenerator.m; sourceTree = "<group>"; };
40CA4049198C55100094DF1F /* PGGenerator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PGGenerator.h; sourceTree = "<group>"; };
D302272A17020F9400594F16 /* PGClassImplementationTemplate.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = PGClassImplementationTemplate.txt; path = res/PGClassImplementationTemplate.txt; sourceTree = "<group>"; };
D306298118E1ED5D00EF745E /* TDTestScaffold.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TDTestScaffold.m; path = test/TDTestScaffold.m; sourceTree = "<group>"; };
D3083AB51705F05C00DA6F95 /* elementsAssign.grammar */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = elementsAssign.grammar; path = res/elementsAssign.grammar; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1132,9 +1138,13 @@
isa = PBXGroup;
children = (
D3383049171C923700CCE513 /* PGMainMenu.xib */,
40CA4046198C3F4C0094DF1F /* PGCLI.h */,
40CA4044198C3E8B0094DF1F /* PGCLI.m */,
D3383043171C923700CCE513 /* PGDocument.h */,
D3383044171C923700CCE513 /* PGDocument.m */,
D3383046171C923700CCE513 /* PGDocument.xib */,
40CA4049198C55100094DF1F /* PGGenerator.h */,
40CA4047198C54AB0094DF1F /* PGGenerator.m */,
D3B22A571703D03F00446945 /* PGTemplates */,
D3A1492A16F8C79600770DEE /* visitor */,
D325FFBC161E4E3200D4EBCC /* ast */,
Expand Down Expand Up @@ -1899,6 +1909,7 @@
files = (
D376F6E318D0B5090064C888 /* PEGKitParser.m in Sources */,
D376F6D018D0B3990064C888 /* PGDelimitedNode.m in Sources */,
40CA4045198C3E8B0094DF1F /* PGCLI.m in Sources */,
D338303E171C923700CCE513 /* main.m in Sources */,
D376F6D418D0B3990064C888 /* PGMultipleNode.m in Sources */,
D376F6CC18D0B3990064C888 /* PGConstantNode.m in Sources */,
Expand All @@ -1912,6 +1923,7 @@
D376F6DF18D0B5020064C888 /* PGParserFactory.m in Sources */,
D376F6DA18D0B3990064C888 /* PGReferenceNode.m in Sources */,
D366C1AD1A5310F200D69669 /* PGNegationNode.m in Sources */,
40CA4048198C54AB0094DF1F /* PGGenerator.m in Sources */,
D376F6EE18D0B5190064C888 /* PGBaseVisitor.m in Sources */,
D376F6DC18D0B3990064C888 /* PGRootNode.m in Sources */,
D376F6C818D0B3990064C888 /* PGCollectionNode.m in Sources */,
Expand Down
24 changes: 24 additions & 0 deletions ParserGenApp/PGCLI.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// PGCLI.h
// PEGKit
//
// Created by Ewan Mellor on 7/29/14.
//
//

#import <Foundation/Foundation.h>


@interface PGCLI : NSObject

/**
* @return true if there are command-line arguments that this class can handle.
*/
-(BOOL)willHandleCommandLine;

/**
* @return The value that should be returned from main.
*/
-(int)handleCommandLine;

@end
117 changes: 117 additions & 0 deletions ParserGenApp/PGCLI.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//
// PGCLI.m
// PEGKit
//
// Created by Ewan Mellor on 7/29/14.
//
//

#import "PGGenerator.h"

#import "PGCLI.h"


#define nsfprintf(__fp, ...) \
fprintf(__fp, "%s\n", [[NSString stringWithFormat:__VA_ARGS__] UTF8String])


@interface PGCLI ()

@property (nonatomic) PGGenerator * generator;
@property (nonatomic) NSString * grammarFile;

@end


@implementation PGCLI


-(instancetype)init {
self = [super init];
if (self) {
_generator = [[PGGenerator alloc] init];
}
return self;
}


-(BOOL)willHandleCommandLine {
[self parseArgs];

return (self.grammarFile != nil);
}


-(int)handleCommandLine {
if (self.generator.destinationPath.length == 0 || self.grammarFile.length == 0) {
nsfprintf(stderr,
@"\n"
@"Usage:\n"
@"\n"
@" ParserGenApp -grammar <file path> -destPath <directory path> <options>\n"
@"\n"
@"Options are any combination of:\n"
@" -parserName <name>\n"
@" -enableARC 1\n"
@" -enableAutomaticErrorRecovery 1\n"
@" -enableHybridDFA 1\n"
@" -enableMemoization 1\n");
return 1;
}

BOOL ok = [self loadGrammar];
if (!ok) {
return 1;
}

ok = [self generate];
if (!ok) {
return 1;
}

return 0;
}


-(void)parseArgs {
NSUserDefaults * ud = [NSUserDefaults standardUserDefaults];

self.grammarFile = [ud stringForKey:@"grammar"];

self.generator.destinationPath = [ud stringForKey:@"destPath"];
if (self.generator.destinationPath == nil) {
self.generator.destinationPath = [ud stringForKey:@"destinationPath"];
}
self.generator.enableARC = [ud boolForKey:@"enableARC"];
self.generator.enableAutomaticErrorRecovery = [ud boolForKey:@"enableAutomaticErrorRecovery"];
self.generator.enableHybridDFA = [ud boolForKey:@"enableHybridDFA"];
self.generator.enableMemoization = [ud boolForKey:@"enableMemoization"];
self.generator.parserName = [ud stringForKey:@"parserName"];
}


-(BOOL)loadGrammar {
NSString * path = [self.grammarFile stringByExpandingTildeInPath];
NSError * err = nil;
NSString * grammar = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&err];
if (grammar == nil) {
nsfprintf(stderr, NSLocalizedString(@"Failed to load grammar: %@", nil), [err localizedDescription]);
return NO;
}
else {
self.generator.grammar = grammar;
return YES;
}
}


-(BOOL)generate {
bool ok = [self.generator generate];
if (!ok) {
nsfprintf(stderr, NSLocalizedString(@"Failed to generate: %@", nil), [self.generator.error localizedDescription]);
}
return ok;
}


@end
90 changes: 13 additions & 77 deletions ParserGenApp/PGDocument.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,13 @@
#import "PGDocument.h"
//#import <PEGKit/PEGKit.h>
#import "PGParserGenVisitor.h"

@interface PGDocument ()
@property (nonatomic, retain) PGParserFactory *factory;
@property (nonatomic, retain) PGRootNode *root;
@property (nonatomic, retain) PGParserGenVisitor *visitor;
@end
#import "PGGenerator.h"

@implementation PGDocument

- (instancetype)init {
self = [super init];
if (self) {
self.factory = [PGParserFactory factory];
_factory.collectTokenKinds = YES;

self.enableARC = YES;
self.enableHybridDFA = YES;
self.enableMemoization = YES;
Expand All @@ -63,9 +55,6 @@ - (void)dealloc {

self.textView = nil;

self.factory = nil;
self.root = nil;
self.visitor = nil;
[super dealloc];
}

Expand Down Expand Up @@ -154,7 +143,18 @@ - (IBAction)generate:(id)sender {
self.error = nil;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self generateWithDestinationPath:destPath parserName:parserName grammar:grammar];
PGGenerator * generator = [[PGGenerator alloc] init];
generator.destinationPath = destPath;
generator.parserName = parserName;
generator.grammar = grammar;
generator.enableARC = self.enableARC;
generator.enableAutomaticErrorRecovery = self.enableAutomaticErrorRecovery;
generator.enableHybridDFA = self.enableHybridDFA;
generator.enableMemoization = self.enableMemoization;
[generator generate];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self done];
});
});
}

Expand Down Expand Up @@ -223,70 +223,6 @@ - (IBAction)reveal:(id)sender {
#pragma mark Private


- (void)generateWithDestinationPath:(NSString *)destPath parserName:(NSString *)parserName grammar:(NSString *)grammar {
NSError *err = nil;
self.root = (id)[_factory ASTFromGrammar:_grammar error:&err];
if (err) {
self.error = err;
goto done;
}

NSAssert([_root.startMethodName length], @"");
NSString *className = self.parserName;
NSAssert([className length], @"");
if (![className hasSuffix:@"Parser"]) {
className = [NSString stringWithFormat:@"%@Parser", className];
}

_root.grammarName = self.parserName;

self.visitor = [[[PGParserGenVisitor alloc] init] autorelease];
_visitor.enableARC = _enableARC;
_visitor.enableHybridDFA = _enableHybridDFA; //NSAssert(_enableHybridDFA, @"");
_visitor.enableMemoization = _enableMemoization;
_visitor.enableAutomaticErrorRecovery = _enableAutomaticErrorRecovery;
_visitor.delegatePreMatchCallbacksOn = _delegatePreMatchCallbacksOn;
_visitor.delegatePostMatchCallbacksOn = _delegatePostMatchCallbacksOn;

@try {
[_root visit:_visitor];
}
@catch (NSException *ex) {
id userInfo = @{NSLocalizedFailureReasonErrorKey: [ex reason]};
NSError *err = [NSError errorWithDomain:[ex name] code:0 userInfo:userInfo];
self.error = err;
goto done;
}

NSString *path = [[NSString stringWithFormat:@"%@/%@.h", destPath, className] stringByExpandingTildeInPath];
err = nil;
if (![_visitor.interfaceOutputString writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&err]) {
NSMutableString *str = [NSMutableString stringWithString:[err localizedFailureReason]];
[str appendFormat:@"\n\n%@", [path stringByDeletingLastPathComponent]];
id dict = [NSMutableDictionary dictionaryWithDictionary:[err userInfo]];
dict[NSLocalizedFailureReasonErrorKey] = str;
self.error = [NSError errorWithDomain:[err domain] code:[err code] userInfo:dict];
goto done;
}

path = [[NSString stringWithFormat:@"%@/%@.m", destPath, className] stringByExpandingTildeInPath];
err = nil;
if (![_visitor.implementationOutputString writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&err]) {
NSMutableString *str = [NSMutableString stringWithString:[err localizedFailureReason]];
[str appendFormat:@"\n\n%@", [path stringByDeletingLastPathComponent]];
id dict = [NSMutableDictionary dictionaryWithDictionary:[err userInfo]];
dict[NSLocalizedFailureReasonErrorKey] = str;
self.error = [NSError errorWithDomain:[err domain] code:[err code] userInfo:dict];
goto done;
}

done:
dispatch_async(dispatch_get_main_queue(), ^(void){
[self done];
});
}


- (void)done {
if (_error) {
[[NSSound soundNamed:@"Basso"] play];
Expand Down
30 changes: 30 additions & 0 deletions ParserGenApp/PGGenerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// PGGenerator.h
// PEGKit
//
// Created by Ewan Mellor on 8/1/14.
//
//

#import <Foundation/Foundation.h>

#import "PGParserFactory.h"


@interface PGGenerator : NSObject

@property (nonatomic, strong) NSString * destinationPath;
@property (nonatomic, assign) BOOL enableARC;
@property (nonatomic, assign) BOOL enableAutomaticErrorRecovery;
@property (nonatomic, assign) BOOL enableHybridDFA;
@property (nonatomic, assign) BOOL enableMemoization;
@property (nonatomic, strong) NSString * parserName;
@property (nonatomic, strong) NSString * grammar;
@property (nonatomic, assign) PGParserFactoryDelegateCallbacksOn delegatePreMatchCallbacksOn;
@property (nonatomic, assign) PGParserFactoryDelegateCallbacksOn delegatePostMatchCallbacksOn;

@property (nonatomic, strong) NSError * error;

-(BOOL)generate;

@end
Loading