Skip to content

Commit

Permalink
Merge pull request #21 from parrt/master
Browse files Browse the repository at this point in the history
Big update to include visitors, update listener names etc...
  • Loading branch information
parrt committed Feb 18, 2012
2 parents f0a852c + c6fd897 commit 9b49005
Show file tree
Hide file tree
Showing 18 changed files with 240 additions and 143 deletions.
8 changes: 8 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
ANTLR v4 Honey Badger early access

Feb 17, 2012

* names changed. visit() -> visitX(). enter/exit() -> enter/exitX()
* capitalizing automatically now. rule s -> SContext not sContext
* no enter/exit method in generic rule context object if rule has alt labels, nor in interfaces.
* dup labels allowed in same rule
* label X or x illegal if rule x exists

Feb 14, 2012

* Fixed https://github.com/antlr/antlr4/issues/8 and lots of other little things.
Expand Down
10 changes: 9 additions & 1 deletion tool/playground/A.g4
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ s : e ;

e : e '*' e -> Mult
| e '+' e -> Add
| INT -> Int
| INT -> primary
| ID -> primary
| '(' e ')' -> Parens
;

/*
primary : EEE;
add : A ;
*/

ID : [a-z]+ ;
INT : [0-9]+ ;
WS : [ \t\n]+ -> skip ;
13 changes: 5 additions & 8 deletions tool/playground/AVisitor.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.Token;

public interface AVisitor<T> {
T visit(AParser.MultContext ctx);
T visit(AParser.ParensContext ctx);
T visit(AParser.sContext ctx);
T visit(AParser.AddContext ctx);
T visit(AParser.IntContext ctx);
T visitMult(AParser.MultContext ctx);
T visitParens(AParser.ParensContext ctx);
T visitS(AParser.SContext ctx);
T visitPrimary(AParser.PrimaryContext ctx);
T visitAdd(AParser.AddContext ctx);
}
115 changes: 89 additions & 26 deletions tool/playground/TestA.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,9 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.antlr.v4.runtime.*;

import java.util.Stack;
import java.io.*;

public class TestA {
/** An example listener that uses a stack to store return values
Expand Down Expand Up @@ -66,45 +62,112 @@ public class TestA {
* Compare this to A2.g4, which adds a field to the context objects
* by using a "returns [int v]" on the expression rule.
*/
public static class Do extends ABaseListener {
Stack<Integer> results = new Stack<Integer>();
// public static class Do extends ABaseListener {
// Stack<Integer> results = new Stack<Integer>();
//
// @Override
// public void exit(AParser.AddContext ctx) {
// results.push( results.pop() + results.pop() );
// System.out.println("Add: " + results.peek());
// }
//
// @Override
// public void exit(AParser.IntContext ctx) {
// results.push( Integer.valueOf(ctx.INT().getText()) );
// System.out.println("Int: "+results.peek());
// }
//
// @Override
// public void exit(AParser.MultContext ctx) {
// results.push( results.pop() * results.pop() );
// System.out.println("Mult: " + results.peek());
// }
//
// @Override
// public void exit(AParser.ParensContext ctx) {
// // result already on stack
// System.out.println("Parens: "+results.peek());
// }
// }
public static class Tracer extends ABaseListener {
@Override
public void enterAdd(AParser.AddContext ctx) {
printMethodName(ctx);
}

@Override
public void enterEveryRule(ParserRuleContext<Token> ctx) {
printMethodName(ctx);
}

@Override
public void enterMult(AParser.MultContext ctx) {
printMethodName(ctx);
}

@Override
public void enterParens(AParser.ParensContext ctx) {
printMethodName(ctx);
}

@Override
public void exit(AParser.AddContext ctx) {
results.push( results.pop() + results.pop() );
System.out.println("Add: " + results.peek());
public void enterS(AParser.SContext ctx) {
printMethodName(ctx);
}

@Override
public void exit(AParser.IntContext ctx) {
results.push( Integer.valueOf(ctx.INT().getText()) );
System.out.println("Int: "+results.peek());
public void exitAdd(AParser.AddContext ctx) {
printMethodName(ctx);
}

@Override
public void exit(AParser.MultContext ctx) {
results.push( results.pop() * results.pop() );
System.out.println("Mult: " + results.peek());
public void exitMult(AParser.MultContext ctx) {
printMethodName(ctx);
}

@Override
public void exit(AParser.ParensContext ctx) {
// result already on stack
System.out.println("Parens: "+results.peek());
public void exitParens(AParser.ParensContext ctx) {
printMethodName(ctx);
}

@Override
public void exitS(AParser.SContext ctx) {
printMethodName(ctx);
}

@Override
public void exitEveryRule(ParserRuleContext<Token> ctx) {
printMethodName(ctx);
}

@Override
public void visitTerminal(ParserRuleContext<Token> ctx, Token symbol) {
printMethodName(ctx);
}

public void printMethodName(ParserRuleContext ctx) {
Throwable t = new Throwable();
StackTraceElement[] stack = t.getStackTrace();
String m = stack[1].getMethodName();
System.out.println(m+"("+ctx.getClass().getSimpleName()+")");
}
}
public static void main(String[] args) throws Exception {
ALexer lexer = new ALexer(new ANTLRFileStream(args[0]));
InputStream is = System.in;
if ( args.length>0 && args[0]!=null ) {
is = new FileInputStream(args[0]);
}
ALexer lexer = new ALexer(new ANTLRInputStream(is));
CommonTokenStream tokens = new CommonTokenStream(lexer);
AParser p = new AParser(tokens);
p.setBuildParseTree(true);
p.addParseListener(new Do());
p.addParseListener(new Tracer());
ParserRuleContext<Token> t = p.s();
System.out.println("tree = "+t.toStringTree(p));

ParseTreeWalker walker = new ParseTreeWalker();
Do doer = new Do();
walker.walk(doer, t);
System.out.println("result from tree walk = "+ doer.results.pop());
// ParseTreeWalker walker = new ParseTreeWalker();
// Do doer = new Do();
// walker.walk(doer, t);
// System.out.println("result from tree walk = "+ doer.results.pop());
}
}
14 changes: 4 additions & 10 deletions tool/playground/TestVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,27 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
*/

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;

public class TestVisitor {
public static class MyVisitor extends ABaseVisitor<Integer> implements AVisitor<Integer> {
@Override
public Integer visit(AParser.AddContext ctx) {
public Integer visitAdd(AParser.AddContext ctx) {
return ctx.e(0).accept(this) + ctx.e(1).accept(this);
}

@Override
public Integer visit(AParser.IntContext ctx) {
return Integer.valueOf(ctx.INT().getText());
}

@Override
public Integer visit(AParser.MultContext ctx) {
public Integer visitMult(AParser.MultContext ctx) {
// return ctx.e(0).accept(this) * ctx.e(1).accept(this);
return visit(ctx.e(0)) * visit(ctx.e(1));
}

@Override
public Integer visit(AParser.ParensContext ctx) {
public Integer visitParens(AParser.ParensContext ctx) {
return ctx.e().accept(this);
}

@Override
public Integer visit(AParser.sContext ctx) {
public Integer visitS(AParser.SContext ctx) {
return visit(ctx.e());
//return ctx.e().accept(this);
}
Expand Down
56 changes: 28 additions & 28 deletions tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import org.antlr.v4.runtime.Token;

public interface <file.grammarName>Listener extends ParseTreeListener\<<InputSymbolType()>\> {
<file.listenerNames:{lname |
void enter(<file.parserName>.<lname>Context ctx);
void exit(<file.parserName>.<lname>Context ctx);}; separator="\n">
void enter<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx);
void exit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx);}; separator="\n">
}
>>

Expand All @@ -47,8 +47,8 @@ import org.antlr.v4.runtime.Token;

public class <file.grammarName>BaseListener implements <file.grammarName>Listener {
<file.listenerNames:{lname |
@Override public void enter(<file.parserName>.<lname>Context ctx) { \}
@Override public void exit(<file.parserName>.<lname>Context ctx) { \}}; separator="\n">
@Override public void enter<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx) { \}
@Override public void exit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx) { \}}; separator="\n">

@Override public void enterEveryRule(ParserRuleContext\<<InputSymbolType()>\> ctx) { }
@Override public void exitEveryRule(ParserRuleContext\<<InputSymbolType()>\> ctx) { }
Expand All @@ -63,7 +63,7 @@ import org.antlr.v4.runtime.Token;

public interface <file.grammarName>Visitor\<T> {
<file.visitorNames:{lname |
T visit(<file.parserName>.<lname>Context ctx);}; separator="\n">
T visit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx);}; separator="\n">
}
>>

Expand All @@ -74,7 +74,7 @@ import org.antlr.v4.runtime.Token;

public class <file.grammarName>BaseVisitor\<T> extends ParseTreeVisitor\<T> implements <file.grammarName>Visitor\<T> {
<file.visitorNames:{lname |
public T visit(<file.parserName>.<lname>Context ctx) { visitChildren(ctx); return null; \}}; separator="\n">
public T visit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx) { visitChildren(ctx); return null; \}}; separator="\n">
}
>>

Expand Down Expand Up @@ -237,7 +237,7 @@ LeftRecursiveRuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,
>>

CodeBlockForOuterMostAlt(currentOuterMostAltCodeBlock, locals, preamble, ops) ::= <<
<if(currentOuterMostAltCodeBlock.altLabel)>_localctx = new <currentOuterMostAltCodeBlock.altLabel>Context(_localctx);<endif>
<if(currentOuterMostAltCodeBlock.altLabel)>_localctx = new <currentOuterMostAltCodeBlock.altLabel; format="cap">Context(_localctx);<endif>
enterOuterAlt(_localctx, <currentOuterMostAltCodeBlock.alt.altNum>);
<CodeBlockForAlt(currentAltCodeBlock=currentOuterMostAltCodeBlock, ...)>
>>
Expand Down Expand Up @@ -503,9 +503,9 @@ ThisRulePropertyRef_stop(r) ::= "_localctx.stop"
ThisRulePropertyRef_text(r) ::= "_input.toString(_localctx.start, _input.LT(-1))"
ThisRulePropertyRef_ctx(r) ::= "_localctx"

NonLocalAttrRef(s) ::= "((<s.ruleName>Context)getInvokingContext(<s.ruleIndex>)).<s.name>"
NonLocalAttrRef(s) ::= "((<s.ruleName; format=\"cap\">Context)getInvokingContext(<s.ruleIndex>)).<s.name>"
SetNonLocalAttr(s, rhsChunks) ::=
"((<s.ruleName>Context)getInvokingContext(<s.ruleIndex>)).<s.name> = <rhsChunks>;"
"((<s.ruleName; format=\"cap\">Context)getInvokingContext(<s.ruleIndex>)).<s.name> = <rhsChunks>;"

AddToLabelList(a) ::= "<ctx(a.label)>.<a.listName>.add(<labelref(a.label)>);"

Expand All @@ -526,17 +526,17 @@ public Token <t.name>(int i) {
>>
ContextRuleGetterDecl(r) ::= <<
public <r.ctxName> <r.name>() {
return (<r.ctxName>)getRuleContext(<r.ctxName>.class,0);
return getRuleContext(<r.ctxName>.class,0);
}
>>
ContextRuleListGetterDecl(r) ::= <<
public List\<? extends <r.ctxName>\> <r.name>() {
return (List\<<r.ctxName>\>)getRuleContexts(<r.ctxName>.class);
return getRuleContexts(<r.ctxName>.class);
}
>>
ContextRuleListIndexedGetterDecl(r) ::= <<
public <r.ctxName> <r.name>(int i) {
return (<r.ctxName>)getRuleContext(<r.ctxName>.class,i);
return getRuleContext(<r.ctxName>.class,i);
}
>>

Expand All @@ -555,48 +555,48 @@ ListLabelName(label) ::= "<label>"
CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);"
CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);"

StructDecl(s,attrs,getters,dispatchMethods,interfaces,extensionMembers,
StructDecl(struct,attrs,getters,dispatchMethods,interfaces,extensionMembers,
superClass={ParserRuleContext\<<InputSymbolType()>>}) ::= <<
public static class <s.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> {
public static class <struct.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> {
<attrs:{a | <a>}; separator="\n">
<getters:{g | <g>}; separator="\n">
<if(s.ctorAttrs)>public <s.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state) { super(parent, state); }<endif>
public <s.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state<s.ctorAttrs:{a | , <a>}>) {
<if(struct.ctorAttrs)>public <struct.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state) { super(parent, state); }<endif>
public <struct.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state<struct.ctorAttrs:{a | , <a>}>) {
super(parent, state);
<s.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n">
<struct.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n">
}
<if(s.provideCopyFrom)> <! don't need copy unless we have subclasses !>
public <s.name>() { }
public void copyFrom(<s.name> ctx) {
<if(struct.provideCopyFrom)> <! don't need copy unless we have subclasses !>
public <struct.name>() { }
public void copyFrom(<struct.name> ctx) {
super.copyFrom(ctx);
<s.attrs:{a | this.<a.name> = ctx.<a.name>;}; separator="\n">
<struct.attrs:{a | this.<a.name> = ctx.<a.name>;}; separator="\n">
}
<endif>
<dispatchMethods; separator="\n">
<extensionMembers; separator="\n">
}
>>

AltLabelStructDecl(s,attrs,getters,dispatchMethods) ::= <<
public static class <s.name> extends <currentRule.name>Context {
AltLabelStructDecl(struct,attrs,getters,dispatchMethods) ::= <<
public static class <struct.name> extends <currentRule.name; format="cap">Context {
<attrs:{a | <a>}; separator="\n">
<getters:{g | <g>}; separator="\n">
public <s.name>(<currentRule.name>Context ctx) { copyFrom(ctx); }
public <struct.name>(<currentRule.name; format="cap">Context ctx) { copyFrom(ctx); }
<dispatchMethods; separator="\n">
}
>>

ListenerDispatchMethod(method) ::= <<
@Override
public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener\<<InputSymbolType()>\> listener) {
if ( listener instanceof <parser.grammarName>Listener ) ((<parser.grammarName>Listener)listener).<if(method.isEnter)>enter<else>exit<endif>(this);
if ( listener instanceof <parser.grammarName>Listener ) ((<parser.grammarName>Listener)listener).<if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">(this);
}
>>

VisitorDispatchMethod(method) ::= <<
@Override
public \<T> T accept(ParseTreeVisitor\<? extends T> visitor) {
if ( visitor instanceof <parser.grammarName>Visitor ) return ((<parser.grammarName>Visitor\<T>)visitor).visit(this);
if ( visitor instanceof <parser.grammarName>Visitor ) return ((<parser.grammarName>Visitor\<T>)visitor).visit<struct.derivedFromName; format="cap">(this);
else return null;
}
>>
Expand Down Expand Up @@ -626,9 +626,9 @@ _localctx.start = _prevctx.start;
>>

recRuleLabeledAltStartAction(ruleName, currentAltLabel, label) ::= <<
_localctx = new <currentAltLabel>Context(new <ruleName>Context(_parentctx, _startState, _p));
_localctx = new <currentAltLabel; format="cap">Context(new <ruleName; format="cap">Context(_parentctx, _startState, _p));
_localctx.addChild(_prevctx);
<if(label)>((<currentAltLabel>Context)_localctx).<label> = _prevctx;<endif>
<if(label)>((<currentAltLabel; format="cap">Context)_localctx).<label> = _prevctx;<endif>
pushNewRecursionContext(_localctx, RULE_<ruleName>);
_localctx.start = _prevctx.start;
>>
Expand Down
Loading

0 comments on commit 9b49005

Please sign in to comment.