alter visitTerminal interface, add visitErrorNode.

This commit is contained in:
Terence Parr 2012-02-26 22:07:45 -08:00
parent 67b2e6d7c1
commit ae08867ff3
6 changed files with 19 additions and 391 deletions

View File

@ -3,9 +3,7 @@ grammar A;
s : e ;
e : e '*' e -> Mult
| e '+' e -> Add
| INT -> primary
| '(' e ')' -> Parens
;
INT : [0-9]+ ;

View File

@ -1,10 +0,0 @@
import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.Token;
public interface AVisitor<T> {
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);
}

View File

@ -1,26 +1,23 @@
grammar T;
@members {
public static class LeafListener extends TBaseListener {
public void exitA(TParser.EContext ctx) {
/*
if (ctx.getChildCount()==3) {
System.out.printf("%s %s %s",ctx.e(0).start.getText(),
ctx.e(1).start.getText(),ctx.e().get(0).start.getText());
}
else System.out.println(ctx.INT(0).start.getText());
*/
public void exitCall(TParser.CallContext ctx) {
System.out.printf("%s %s",ctx.e().start.getText(),
ctx.eList());
}
}}
} public void exitInt(TParser.IntContext ctx) {
System.out.println(ctx.INT().getText());
}
}
s
@init {setBuildParseTree(true);}
@after { System.out.println($r.ctx.toStringTree(this)); ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(new LeafListener(), $r.ctx);}
: r=e ;
e : e op='*' e
| e op='+' e
| e '++'
| INT
;
e : e '(' eList ')' -> Call
| INT -> Int
;
eList : e (',' e)* ;
MULT: '*' ;
ADD : '+' ;
INT : [0-9]+ ;

View File

@ -1,233 +0,0 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import org.antlr.v4.runtime.*;
import java.io.*;
public class TestA {
/** An example listener that uses a stack to store return values
* so that exit methods executed on notes further up the parse tree
* can see the results of these computations.
*
* Because we are using only the exit routines, the same listener works
* as a parse listener and is a parse tree listener. It generates
* the following output from input 3+4*5:
Int: 3
Int: 4
Int: 5
Mult: 20
Add: 23
tree = (s (e (e 3) + (e (e 4) * (e 5))))
Int: 3
Int: 4
Int: 5
Mult: 20
Add: 23
result from tree walk = 23
* The key things to notice are that there are no actions
* and the labels in the grammar--it is completely language neutral.
* Also, I have labeled each alternative so that we get a different
* context object. That way we get a listener method for each
* alternative.
*
* 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>();
//
// @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 enterS(AParser.SContext ctx) {
printMethodName(ctx);
}
@Override
public void exitAdd(AParser.AddContext ctx) {
printMethodName(ctx);
}
@Override
public void exitMult(AParser.MultContext ctx) {
printMethodName(ctx);
}
@Override
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);
}
@Override
public void enterPrimary(AParser.PrimaryContext ctx) {
printMethodName(ctx);
}
@Override
public void exitPrimary(AParser.PrimaryContext ctx) {
printMethodName(ctx);
}
}
public static class TraceDuringParse extends ABaseParseListener {
@Override
public void enterNonLRRule(ParserRuleContext<Token> ctx) {
printMethodName(ctx);
}
@Override
public void enterS(ParserRuleContext<Token> ctx) {
printMethodName(ctx);
}
@Override
public void exitAdd(AParser.AddContext ctx) {
printMethodName(ctx);
}
@Override
public void exitEveryRule(ParserRuleContext<Token> ctx) {
printMethodName(ctx);
}
@Override
public void exitMult(AParser.MultContext ctx) {
printMethodName(ctx);
}
@Override
public void exitParens(AParser.ParensContext ctx) {
printMethodName(ctx);
}
@Override
public void exitPrimary(AParser.PrimaryContext ctx) {
printMethodName(ctx);
}
@Override
public void exitS(AParser.SContext ctx) {
printMethodName(ctx);
}
@Override
public void visitTerminal(ParserRuleContext<Token> ctx, Token symbol) {
printMethodName(ctx);
System.out.println("visiting "+symbol);
}
}
public static 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 {
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 TraceDuringParse());
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());
}
}

View File

@ -1,66 +1,15 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
public class TestT {
public static void main(String[] args) throws Exception {
TLexer t = new TLexer(new ANTLRFileStream(args[0]));
CommonTokenStream tokens = new CommonTokenStream(t);
tokens.fill();
for (Object tok : tokens.getTokens()) {
System.out.println(tok);
}
TParser p = new TParser(tokens);
p.setBuildParseTree(true);
// final TParser.sContext tree = p.s();
// System.out.println(tree.toStringTree(p));
// TreeViewer v = new TreeViewer(p, tree);
// v.setHighlightedBoxColor(TreeViewer.LIGHT_RED);
// v.addHighlightedNodes(new ArrayList<Tree>() {{
// ParseTree c0 = tree.getChild(0);
// add(c0);
// add(c0.getChild(0));
// }});
// v.open();
// tree.inspect(p);
//
// ParseTreeWalker walker = new ParseTreeWalker();
// TListener listener = new BlankTListener() {
// public void enterEveryRule(ParserRuleContext ctx) {
// System.out.println("enter rule "+TParser.ruleNames[ctx.ruleIndex]);
// }
// public void exitRule(TParser.DoIfContext ctx) { // specific to rule ifstat
// System.out.println("exit rule ifstat");
// }
// };
// walker.walk(listener, tree);
CharStream input = new ANTLRFileStream(args[0]);
TLexer lex = new TLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lex);
TParser parser = new TParser(tokens);
parser.setBuildParseTree(true);
parser.s();
}
}

View File

@ -1,73 +0,0 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import org.antlr.v4.runtime.*;
public class TestVisitor {
public static class MyVisitor extends ABaseVisitor<Integer> implements AVisitor<Integer> {
@Override
public Integer visitAdd(AParser.AddContext ctx) {
return visit(ctx.e(0)) + visit(ctx.e(1));
}
@Override
public Integer visitMult(AParser.MultContext ctx) {
return visit(ctx.e(0)) * visit(ctx.e(1));
}
@Override
public Integer visitParens(AParser.ParensContext ctx) {
return visit(ctx.e());
}
@Override
public Integer visitS(AParser.SContext ctx) {
return visit(ctx.e());
}
@Override
public Integer visitPrimary(AParser.PrimaryContext ctx) {
return Integer.valueOf(ctx.INT().getText());
}
}
public static void main(String[] args) throws Exception {
ALexer lexer = new ALexer(new ANTLRFileStream(args[0]));
CommonTokenStream tokens = new CommonTokenStream(lexer);
AParser p = new AParser(tokens);
p.setBuildParseTree(true);
ParserRuleContext<Token> t = p.s();
System.out.println("tree = "+t.toStringTree(p));
MyVisitor visitor = new MyVisitor();
Integer result = visitor.visit(t);
// Integer result = t.accept(visitor);
System.out.println("result from tree walk = " + result);
}
}