[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