Skip to content

Commit

Permalink
Implement support for optional token and rule getters
Browse files Browse the repository at this point in the history
  • Loading branch information
sharwell committed Jan 4, 2017
1 parent 16c8054 commit 333aac5
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 12 deletions.
32 changes: 29 additions & 3 deletions src/ParserRuleContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,19 @@ export class ParserRuleContext extends RuleContext {
return this.children[i];
}

let result = this.tryGetChild(i, ctxType);
if (result === undefined) {
throw new Error("The specified node does not exist");
}

return result;
}

tryGetChild<T extends ParseTree>(i: number, ctxType: { new (...args: any[]): T; }): T | undefined {
if (!this.children || i < 0 || i >= this.children.length) {
return undefined;
}

let j: number = -1; // what node with ctxType have we found?
for (let o of this.children) {
if (o instanceof ctxType) {
Expand All @@ -207,14 +220,23 @@ export class ParserRuleContext extends RuleContext {
}
}

throw new Error("The specified node does not exist");
return undefined;
}

getToken(ttype: number, i: number): TerminalNode {
if (!this.children || i < 0 || i >= this.children.length) {
let result = this.tryGetToken(ttype, i);
if (result === undefined) {
throw new Error("The specified token does not exist");
}

return result;
}

tryGetToken(ttype: number, i: number): TerminalNode | undefined {
if (!this.children || i < 0 || i >= this.children.length) {
return undefined;
}

let j: number = -1; // what token with ttype have we found?
for (let o of this.children) {
if (o instanceof TerminalNode) {
Expand All @@ -228,7 +250,7 @@ export class ParserRuleContext extends RuleContext {
}
}

throw new Error("The specified token does not exist");
return undefined;
}

getTokens(ttype: number): TerminalNode[] {
Expand Down Expand Up @@ -265,6 +287,10 @@ export class ParserRuleContext extends RuleContext {
throw new Error("Required ctxType was not provided");
}

tryGetRuleContext<T extends ParserRuleContext>(i: number, ctxType: { new (...args: any[]): T; }): T | undefined {
return this.tryGetChild(i, ctxType);
}

getRuleContexts<T extends ParserRuleContext>(ctxType: { new (...args: any[]): T; }): T[] {
let contexts: T[] = [];
if (!this.children) {
Expand Down
6 changes: 3 additions & 3 deletions tool/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ Licensed under the BSD-3-Clause license. See LICENSE file in the project root fo
<dependency>
<groupId>com.tunnelvisionlabs</groupId>
<artifactId>antlr4</artifactId>
<version>4.6.0.1</version>
<version>4.6.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.tunnelvisionlabs</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.6.0.1</version>
<version>4.6.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -223,7 +223,7 @@ Licensed under the BSD-3-Clause license. See LICENSE file in the project root fo
<plugin>
<groupId>com.tunnelvisionlabs</groupId>
<artifactId>antlr4-testgen-maven-plugin</artifactId>
<version>4.6.0.1</version>
<version>4.6.1-SNAPSHOT</version>
<executions>
<execution>
<goals>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -699,8 +699,8 @@ TokenListDecl(t) ::= "_<t.name>: Token[] = []"
RuleContextDecl(r) ::= "_<r.name>: <r.ctxName>"
RuleContextListDecl(rdecl) ::= "_<rdecl.name>: <rdecl.ctxName>[] = []"

ContextTokenGetterDecl(t) ::=
"public <t.name>(): TerminalNode { return this.getToken(<parser.name>.<t.name>, 0); }"
ContextTokenGetterDecl(t, optional) ::=
"public <t.name>(): TerminalNode<if(optional)> | undefined<endif> { return this.<if(optional)>tryG<else>g<endif>etToken(<parser.name>.<t.name>, 0); }"
ContextTokenListGetterDecl(t) ::=
"public <t.name>(): TerminalNode[];"
ContextTokenListIndexedGetterDecl(t) ::= <<
Expand All @@ -713,9 +713,9 @@ public <t.name>(i?: number): TerminalNode | TerminalNode[] {
}
}
>>
ContextRuleGetterDecl(r) ::= <<
public <r.name>(): <r.ctxName> {
return this.getRuleContext(0, <r.ctxName>);
ContextRuleGetterDecl(r, optional) ::= <<
public <r.name>(): <r.ctxName><if(optional)> | undefined<endif> {
return this.<if(optional)>tryG<else>g<endif>etRuleContext(0, <r.ctxName>);
}
>>
ContextRuleListGetterDecl(r) ::= <<
Expand Down

0 comments on commit 333aac5

Please sign in to comment.