[antlr-interest] Return values from listener methods (was "Appropriate use of honey badger listeners")

Terence Parr parrt at cs.usfca.edu
Sat Jan 14 09:59:11 PST 2012


Yeah, simplicity usually wins! All of the solutions I've been looking at are very complicated and actually don't require ANTLR at all, except for perhaps a factory for the context objects.
Ter
On Jan 14, 2012, at 4:31 AM, Oliver Zeigermann wrote:

> I agree to what Sam says. Keeping it simple and using the means Java
> provides anyway is the solution to me. I think ANTLR could introduce a
> sensible general abstraction to this. Rahter provide best practices..
> 
> I have an expression parser that does not generate a result, but
> rather a heterogeneous tree using exactly the same stack stuff as Sam
> only that I put Expression objects on a stack.
> 
> Heterogeneous trees could also hold a reference to the parse tree they
> were created from. In case you need them later.
> 
> My code that covers creating data structures from parses using
> multiply approaches has grown a little bit too large to share on a
> mailing list. If anyone is interested, I could set up a project
> somewhere. For now, here is a fraction of my expression listener
> 
> 
> 	static class ExpressionASTConstructorListener extends BlankExprV4Listener {
> 
> 		private final Stack<Expression> stack = new Stack<Expression>();
> 
> 		@Override
> 		public void exitRule(atomContext ctx) {
> 			final Number number = new Number(ctx._tINT.getText());
> 			stack.push(number);
> 		}
> 
> 		@Override
> 		public void exitRule(mulExprContext ctx) {
> 			final Expression expr;
> 			Expression leftExpr = stack.pop();
> 			String op = ctx.mdop.op.getText();
> 			Expression rightExpr = stack.pop();
> 			Operation operation = new Operation(op, leftExpr, rightExpr);
> 			expr = operation;
> 			stack.push(expr);
> 		}
> 
> 		@Override
> 		public void exitRule(addExprContext ctx) {
> 			final Expression expr;
> 			Expression leftExpr = stack.pop();
> 			String op = ctx.pmop.op.getText();
> 			Expression rightExpr = stack.pop();
> 			Operation operation = new Operation(op, leftExpr, rightExpr);
> 			expr = operation;
> 			stack.push(expr);
> 		}
> 	}
> 
> for a grammar like this
> 
> expr
> : '(' e=expr ')' -> parenExpr
> | left=expr mdop=mdOp right=expr -> mulExpr
> | left=expr pmop=pmOp right=expr -> addExpr
> | atom -> atomExpr
> ;
> 
> - Oliver
> 
> 2012/1/13 Terence Parr <parrt at cs.usfca.edu>:
>> 
>> On Jan 12, 2012, at 1:59 PM, Sam Harwell wrote:
>> 
>>> I've used listeners for several tasks in ANTLRWorks 2 and haven't
>>> encountered any problems in returning values which I wasn't able to work
>>> around in a clean manner.
>>> 
>>> For the case of expressions like your example below, once you realize that
>>> exitRule behaves as an RPN calculator you just use a simple stack to track
>>> computed results. For other tasks I've used stacks, flags, counters, or
>>> whatever else was relevant to the specific task.
>>> 
>>> For a simple calculator, you might have this:
>>> 
>>> public void exitRule(multContext context) {
>>>    double right = stack.pop();
>>>    double left = stack.pop();
>>>    stack.push(left * right);
>>> }
>>> 
>>> If you don't mind reversing the operand order of a commutative operator, you
>>> could also write:
>>> 
>>> public void exitRule(multContext context) {
>>>    stack.push(stack.pop() * stack.pop());
>>> }
>> 
>> This seems like a good solution for expressions. I wonder if we can come up with a solution that users don't have to manage…
>> 
>> Ter
>> 
>> List: http://www.antlr.org/mailman/listinfo/antlr-interest
>> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address



More information about the antlr-interest mailing list