Antlr4 RuleContext, hashCode, equals() problems

48 views
Skip to first unread message

Graham Wideman

unread,
Nov 26, 2012, 2:53:52 AM11/26/12
to antlr-di...@googlegroups.com
Hi folks, especially Ter,
I am trying to hook up an Antlr4 parse tree to a Swing Outline (tree-table component) and have run into a vexing puzzle with identity of parse tree nodes.

The aggravating issue is that Outline (probably also JTree) distinguishes nodes using Swing's TreePath, which expects tree node data (here Antlr ParseTree nodes) to differ based on node.equals().

Unfortunately, Antlr4's RuleContext overrides equals (to use hashCode()), and also sets hashCode such that many children of each parent return the same hash code, if they are of the same type. Needless to say, this breaks Swing Outline/Tree behavior.

So, for example, in parsing XML (using square brackets to avoid forum trouble!):

[document]
  [actions]
    [action]some action[/action]
    [action]another action[/action]
  [/actions]
[/document]


... in the parse tree, the two action RuleContexts will have the same hashCode. (I've run an extended version of the book's XML sample which prints out hashCode for each node).

(a) this seems unlikely to have been intentional
(b) I'm pretty sure that parse tree nodes shouldn't be considered equal if they are different children of the same parent. Even if one considers "equal" to be about "value", then the index within the parent is surely part of that value?
(c) Even if these is some rationale for same-type children to have same hashCode, that's not the strategy for TerminalNodes, which do not override the stricter Object.equals().

So, is this a bug? Does ANTLR require it to be this way for some reason?  How might one intervene most gracefully to arrive at a parse tree in which the RuleContext equals() method does distinguish same-type children of the same parent?

Thanks,
Graham


Sam Harwell

unread,
Nov 26, 2012, 3:16:06 AM11/26/12
to antlr-di...@googlegroups.com

In the past, the hashcode/equals overrides in RuleContext were required for correct functionality. This is no longer the case and those methods will be removed.

https://github.com/antlr/antlr4/issues/87

 

--

Sam Harwell

Owner, Lead Developer

http://tunnelvisionlabs.com

--
 
 

Graham Wideman

unread,
Nov 26, 2012, 6:22:15 AM11/26/12
to antlr-di...@googlegroups.com
Hi Sam -- I see there's a new commit 6421e31, does this mean that the problem has gone away and all I need is to download the latest source?  If so -- woohoo! And thanks!

Terence Parr

unread,
Nov 26, 2012, 11:46:58 AM11/26/12
to antlr-di...@googlegroups.com
actually, the tree model in swing was specifically designed to address what trees look like. the

https://github.com/antlr/antlr4/blob/master/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeLayoutAdaptor.java

does something similar for our tree layout engine.

Ter
> --
>
>

Graham Wideman

unread,
Nov 26, 2012, 11:48:56 PM11/26/12
to antlr-di...@googlegroups.com
Hi Ter and Sam,

OK, FWIW, now that I'm using today's version of ANTLR4, my parse-tree-to-Swing-Outline test is working nicely.

Ter: Yes indeed, to use Outline or JTree you have to furnish an implementation of TreeModel. And TreeModel is simply an interface to whatever underlying data you have, it doesn't necessarily have data of its own.

However, the problem is that TreeModel doesn't actually cover all responsibilities needed to separate visual tree from your data (in this case, a parse tree), notably the responsibility to define how to distinguish/identify nodes that are to be displayed as distinct.

The case in point is that JTree and Outline rely on TreePath to distinguish visual nodes, and TreePath relies on data object's equals(). In particular, those components expect equals() to return false for distinct children of the same parent node regardless of whether they might otherwise be considered of equal "value".

So in cases like that, the only solution I've seen so far is to build your own parallel data structure (possibly using DefaultMutableTreeNode)  that has node-compares that distinguish different children of same parent. But this introduces a whole lot more complexity associated with maintaining the parallel data structure in sync with the underlying application data.

However, now that RuleContext hashCode and equals() have reverted to underlying Object implementations, I think all is well!

-- Graham

Terence Parr

unread,
Nov 27, 2012, 3:42:20 PM11/27/12
to antlr-di...@googlegroups.com
woot! thanks goes to Sam for fixing that.
T
> --
>
>

Reply all
Reply to author
Forward
0 new messages