Skip to content

Commit

Permalink
* FIX: Can now add actions to Empty Alternatives
Browse files Browse the repository at this point in the history
* adding create table stmt test
  • Loading branch information
itod committed Mar 27, 2014
1 parent 73996dd commit 590e2aa
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 16 deletions.
4 changes: 4 additions & 0 deletions PEGKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
D31BBCB018E472300003FFA3 /* CreateTableStmtParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = D31BBCAF18E4722F0003FFA3 /* CreateTableStmtParserTest.m */; };
D31BBCB318E4725F0003FFA3 /* CreateTableStmtParser.m in Sources */ = {isa = PBXBuildFile; fileRef = D31BBCB218E4725F0003FFA3 /* CreateTableStmtParser.m */; };
D31BBCB518E472850003FFA3 /* create_table_stmt.grammar in Resources */ = {isa = PBXBuildFile; fileRef = D31BBCB418E472850003FFA3 /* create_table_stmt.grammar */; };
D31BBCB718E482C60003FFA3 /* PGPredictElseEmptyTemplate.txt in Resources */ = {isa = PBXBuildFile; fileRef = D31BBCB618E482C60003FFA3 /* PGPredictElseEmptyTemplate.txt */; };
D31C40A51779634700A1B8B7 /* JavaScriptWhitespaceParser.m in Sources */ = {isa = PBXBuildFile; fileRef = D31C40A41779634700A1B8B7 /* JavaScriptWhitespaceParser.m */; };
D3344F4917405B4B00598362 /* JSRecoveryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = D3344F4817405B4B00598362 /* JSRecoveryTest.m */; };
D337F07E15D5AE7B00C83AED /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D337F07C15D5AE7B00C83AED /* InfoPlist.strings */; };
Expand Down Expand Up @@ -494,6 +495,7 @@
D31BBCB118E4725F0003FFA3 /* CreateTableStmtParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CreateTableStmtParser.h; path = test/CreateTableStmtParser.h; sourceTree = "<group>"; };
D31BBCB218E4725F0003FFA3 /* CreateTableStmtParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CreateTableStmtParser.m; path = test/CreateTableStmtParser.m; sourceTree = "<group>"; };
D31BBCB418E472850003FFA3 /* create_table_stmt.grammar */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = create_table_stmt.grammar; path = res/create_table_stmt.grammar; sourceTree = "<group>"; };
D31BBCB618E482C60003FFA3 /* PGPredictElseEmptyTemplate.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = PGPredictElseEmptyTemplate.txt; path = res/PGPredictElseEmptyTemplate.txt; sourceTree = "<group>"; };
D31C40A41779634700A1B8B7 /* JavaScriptWhitespaceParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JavaScriptWhitespaceParser.m; path = test/JavaScriptWhitespaceParser.m; sourceTree = "<group>"; };
D3344F4817405B4B00598362 /* JSRecoveryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JSRecoveryTest.m; path = test/JSRecoveryTest.m; sourceTree = "<group>"; };
D33724D816FA62D400D30459 /* PKDelimitDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PKDelimitDescriptor.h; path = src/PKDelimitDescriptor.h; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -1161,6 +1163,7 @@
D3B22A3D17026FBE00446945 /* PGPredictElseIfTemplate.txt */,
D3B63A251706509800BA9DBF /* PGSpeculateElseIfTemplate.txt */,
D3B22A3E17026FBE00446945 /* PGPredictElseTemplate.txt */,
D31BBCB618E482C60003FFA3 /* PGPredictElseEmptyTemplate.txt */,
D3B63A4E170918E700BA9DBF /* PGPredictEndIfTemplate.txt */,
D3B22A431702993B00446945 /* PGOptionalSpeculateTemplate.txt */,
D3B63A76170A460800BA9DBF /* PGOptionalPredictTemplate.txt */,
Expand Down Expand Up @@ -1583,6 +1586,7 @@
files = (
D37D8E361571A5A200CDB822 /* css.grammar in Resources */,
D37D8E391571A5A200CDB822 /* html.grammar in Resources */,
D31BBCB718E482C60003FFA3 /* PGPredictElseEmptyTemplate.txt in Resources */,
D37D8E3D1571A5A200CDB822 /* json_with_comments.grammar in Resources */,
D37D8E451571A5A200CDB822 /* javascript.grammar in Resources */,
D337F07E15D5AE7B00C83AED /* InfoPlist.strings in Resources */,
Expand Down
2 changes: 1 addition & 1 deletion ParserGenApp/PGDefinitionPhaseVisitor.m
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ - (void)visitAlternation:(PGAlternationNode *)node {

do {
PGBaseNode *lhs = node.children[0];
simplify = PGNodeTypeAlternation == lhs.type;
simplify = PGNodeTypeAlternation == lhs.type && !lhs.actionNode;

// nested Alts should always be on the lhs. never on rhs.
NSAssert(PGNodeTypeAlternation != [(PGBaseNode *)node.children[1] type], @"");
Expand Down
20 changes: 17 additions & 3 deletions ParserGenApp/PGParserGenVisitor.m
Original file line number Diff line number Diff line change
Expand Up @@ -711,10 +711,16 @@ - (NSMutableString *)recurseAlt:(PGAlternationNode *)node la:(NSMutableArray *)l
// recurse
NSUInteger idx = 0;
for (PGBaseNode *child in node.children) {
BOOL isEmpty = NO;

if ([self isEmptyNode:child]) {
isEmpty = YES;
node.hasEmptyAlternative = YES;
++idx;
continue;

if (!child.actionNode) {
++idx;
continue;
}
}

id vars = [NSMutableDictionary dictionary];
Expand All @@ -725,8 +731,13 @@ - (NSMutableString *)recurseAlt:(PGAlternationNode *)node la:(NSMutableArray *)l
vars[DEPTH] = @(_depth);
vars[NEEDS_BACKTRACK] = @(_needsBacktracking);

NSString *templateName = nil;
if (isEmpty) {
templateName = @"PGPredictElseEmptyTemplate";
} else {
templateName = [result length] ? @"PGPredictElseIfTemplate" : @"PGPredictIfTemplate";
}
// process template. cannot test `idx` here to determine `if` vs `else` due to possible Empty child borking `idx`
NSString *templateName = [result length] ? @"PGPredictElseIfTemplate" : @"PGPredictIfTemplate";
NSString *output = [_engine processTemplate:[self templateStringNamed:templateName] withVariables:vars];
[result appendString:output];

Expand Down Expand Up @@ -845,6 +856,9 @@ - (void)visitAlternation:(PGAlternationNode *)node {
}
[childStr appendString:elseStr];

// action
[childStr appendString:[self actionStringFrom:node.actionNode]];

// push
[self push:childStr];
}
Expand Down
1 change: 1 addition & 0 deletions res/PGPredictElseEmptyTemplate.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{%for 1 to depth %} {%/for%}} else { {{childString}}
9 changes: 6 additions & 3 deletions res/create_table_stmt.grammar
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
createTableStmt = 'CREATE'! tempOpt 'TABLE'! existsOpt databaseName ';'
createTableStmt = 'CREATE'! tempOpt 'TABLE'! existsOpt databaseName ';'!
{
NSString *dbName = POP();
BOOL ifExists = POP_BOOL();
BOOL ifNotExists = POP_BOOL();
BOOL isTemp = POP_BOOL();
NSLog(@"%@, %d, %d", dbName, ifExists, isTemp);
NSLog(@"create table: %@, %d, %d", dbName, ifNotExists, isTemp);
// go to town
// myCreateTable(dbName, ifExists, isTemp);
};

databaseName = QuotedString
{
// pop the string value of the `PKToken` on the top of the stack
NSString *dbName = POP_STR();
// trim quotes
dbName = [dbName substringWithRange:NSMakeRange(1, [dbName length]-2)];
// leave it on the stack for later
PUSH(dbName);
};

Expand Down
33 changes: 26 additions & 7 deletions test/CreateTableStmtParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ - (void)createTableStmt_ {
[self match:CREATETABLESTMT_TOKEN_KIND_TABLE discard:YES];
[self existsOpt_];
[self databaseName_];
[self match:CREATETABLESTMT_TOKEN_KIND_SEMI_COLON discard:NO];
[self match:CREATETABLESTMT_TOKEN_KIND_SEMI_COLON discard:YES];
[self execute:(id)^{

NSString *dbName = POP();
BOOL ifExists = POP_BOOL();
BOOL ifNotExists = POP_BOOL();
BOOL isTemp = POP_BOOL();
NSLog(@"%@, %d, %d", dbName, ifExists, isTemp);
NSLog(@"create table: %@, %d, %d", dbName, ifNotExists, isTemp);
// go to town
// myCreateTable(dbName, ifExists, isTemp);

Expand All @@ -114,9 +114,11 @@ - (void)databaseName_ {
[self matchQuotedString:NO];
[self execute:(id)^{

// pop the string value of the `PKToken` on the top of the stack
NSString *dbName = POP_STR();
// trim quotes
dbName = [dbName substringWithRange:NSMakeRange(1, [dbName length]-2)];
// leave it on the stack for later
PUSH(dbName);

}];
Expand All @@ -126,10 +128,22 @@ - (void)databaseName_ {

- (void)tempOpt_ {

if ([self predicts:CREATETABLESTMT_TOKEN_KIND_TEMP, 0]) {
[self match:CREATETABLESTMT_TOKEN_KIND_TEMP discard:YES];
} else if ([self predicts:CREATETABLESTMT_TOKEN_KIND_TEMPORARY, 0]) {
[self match:CREATETABLESTMT_TOKEN_KIND_TEMPORARY discard:YES];
if ([self predicts:CREATETABLESTMT_TOKEN_KIND_TEMP, CREATETABLESTMT_TOKEN_KIND_TEMPORARY, 0]) {
if ([self predicts:CREATETABLESTMT_TOKEN_KIND_TEMP, 0]) {
[self match:CREATETABLESTMT_TOKEN_KIND_TEMP discard:YES];
} else if ([self predicts:CREATETABLESTMT_TOKEN_KIND_TEMPORARY, 0]) {
[self match:CREATETABLESTMT_TOKEN_KIND_TEMPORARY discard:YES];
} else {
[self raise:@"No viable alternative found in rule 'tempOpt'."];
}
[self execute:(id)^{
PUSH(@YES);
}];
} else {
[self matchEmpty:NO];
[self execute:(id)^{
PUSH(@NO);
}];
}

[self fireDelegateSelector:@selector(parser:didMatchTempOpt:)];
Expand All @@ -144,6 +158,11 @@ - (void)existsOpt_ {
[self execute:(id)^{
PUSH(@YES);
}];
} else {
[self matchEmpty:NO];
[self execute:(id)^{
PUSH(@NO);
}];
}

[self fireDelegateSelector:@selector(parser:didMatchExistsOpt:)];
Expand Down
60 changes: 58 additions & 2 deletions test/CreateTableStmtParserTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,69 @@ - (void)tearDown {
}


- (void)testCompleteStruct {
- (void)testNoTempNoIfExists {
NSString *s = @"CREATE TABLE 'foo';";

NSError *err = nil;
[_parser parseString:s error:&err];
PKAssembly *res = [_parser parseString:s error:&err];
TDNil(err);

TDEqualObjects(TDAssembly(@"[]CREATE/TABLE/'foo'/;^"), [res description]);
}


- (void)testNoTemp {
NSString *s = @"CREATE TABLE IF NOT EXISTS 'foo';";

NSError *err = nil;
PKAssembly *res = [_parser parseString:s error:&err];
TDNil(err);

TDEqualObjects(TDAssembly(@"[]CREATE/TABLE/IF/NOT/EXISTS/'foo'/;^"), [res description]);
}


- (void)testTemp {
NSString *s = @"CREATE TEMP TABLE IF NOT EXISTS 'foo';";

NSError *err = nil;
PKAssembly *res = [_parser parseString:s error:&err];
TDNil(err);

TDEqualObjects(TDAssembly(@"[]CREATE/TEMP/TABLE/IF/NOT/EXISTS/'foo'/;^"), [res description]);
}


- (void)testTempNoIfExists {
NSString *s = @"CREATE TEMP TABLE 'foo';";

NSError *err = nil;
PKAssembly *res = [_parser parseString:s error:&err];
TDNil(err);

TDEqualObjects(TDAssembly(@"[]CREATE/TEMP/TABLE/'foo'/;^"), [res description]);
}


- (void)testTemporary {
NSString *s = @"CREATE TEMPORARY TABLE IF NOT EXISTS 'foo';";

NSError *err = nil;
PKAssembly *res = [_parser parseString:s error:&err];
TDNil(err);

TDEqualObjects(TDAssembly(@"[]CREATE/TEMPORARY/TABLE/IF/NOT/EXISTS/'foo'/;^"), [res description]);
}


- (void)testTemporaryNoIfExists {
NSString *s = @"CREATE TEMPORARY TABLE 'foo';";

NSError *err = nil;
PKAssembly *res = [_parser parseString:s error:&err];
TDNil(err);

TDEqualObjects(TDAssembly(@"[]CREATE/TEMPORARY/TABLE/'foo'/;^"), [res description]);
}


Expand Down

0 comments on commit 590e2aa

Please sign in to comment.