-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Add an iterative version of the ParseTreeWalker #1231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
53f2a67
Add an iterative version of the ParseTreeWalker
twz123 7ca7acd
Use two queues instead of a custom linked memory structure
twz123 ea31615
Use the iterative version of the ParseTreeWalker as default implement…
twz123 cc59a69
Add myself to the list of contributors using the date of my first com…
twz123 d1bc0f5
Merge remote-tracking branch 'origin/master' into iterative-tree-walker
twz123 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
runtime/Java/src/org/antlr/v4/runtime/tree/IterativeParseTreeWalker.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| /* | ||
| * [The "BSD license"] | ||
| * Copyright (c) 2012 Terence Parr | ||
| * Copyright (c) 2012 Sam Harwell | ||
| * 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. | ||
| */ | ||
|
|
||
| package org.antlr.v4.runtime.tree; | ||
|
|
||
| import java.util.ArrayDeque; | ||
| import java.util.Deque; | ||
|
|
||
| import org.antlr.v4.runtime.misc.IntegerStack; | ||
|
|
||
| /** | ||
| * An iterative (read: non-recursive) pre-order and post-order tree walker that | ||
| * doesn't use the thread stack but heap-based stacks. Makes it possible to | ||
| * process deeply nested parse trees. | ||
| */ | ||
| public class IterativeParseTreeWalker extends ParseTreeWalker { | ||
|
|
||
| @Override | ||
| public void walk(ParseTreeListener listener, ParseTree t) { | ||
|
|
||
| final Deque<ParseTree> nodeStack = new ArrayDeque<ParseTree>(); | ||
| final IntegerStack indexStack = new IntegerStack(); | ||
|
|
||
| ParseTree currentNode = t; | ||
| int currentIndex = 0; | ||
|
|
||
| while (currentNode != null) { | ||
|
|
||
| // pre-order visit | ||
| if (currentNode instanceof ErrorNode) { | ||
| listener.visitErrorNode((ErrorNode) currentNode); | ||
| } else if (currentNode instanceof TerminalNode) { | ||
| listener.visitTerminal((TerminalNode) currentNode); | ||
| } else { | ||
| final RuleNode r = (RuleNode) currentNode; | ||
| enterRule(listener, r); | ||
| } | ||
|
|
||
| // Move down to first child, if exists | ||
| if (currentNode.getChildCount() > 0) { | ||
| nodeStack.push(currentNode); | ||
| indexStack.push(currentIndex); | ||
| currentIndex = 0; | ||
| currentNode = currentNode.getChild(0); | ||
| continue; | ||
| } | ||
|
|
||
| // No child nodes, so walk tree | ||
| do { | ||
|
|
||
| // post-order visit | ||
| if (currentNode instanceof RuleNode) { | ||
| exitRule(listener, (RuleNode) currentNode); | ||
| } | ||
|
|
||
| // No parent, so no siblings | ||
| if (nodeStack.isEmpty()) { | ||
| currentNode = null; | ||
| currentIndex = 0; | ||
| break; | ||
| } | ||
|
|
||
| // Move to next sibling if possible | ||
| currentNode = nodeStack.peek().getChild(++currentIndex); | ||
| if (currentNode != null) { | ||
| break; | ||
| } | ||
|
|
||
| // No next, sibling, so move up | ||
| currentNode = nodeStack.pop(); | ||
| currentIndex = indexStack.pop(); | ||
|
|
||
| } while (currentNode != null); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that copyright wrong? Neither exists this file since 2012 nor was it written by Sam + Ter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The year is particularly interesting. It turns out keeping the year constant and using the year when the code base started provides the longest and strongest copyright protections. If you want to see some of the details on this, take a look at the long and probably very boring comments in DotNetAnalyzers/StyleCopAnalyzers#1661.
The use of mine and Terence's names has to do with copyright assignment, which is (to the best of my knowledge) common practice in a number of circles. There are three ways we work to ensure the original author of patches remains recognized for the life of the project:
📝 I am not a lawyer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, you certainly have your reasons, but to me it feels wrong. The header says the file exists since 2012, which is plain wrong. If you always use the same year then you wouldn't need individual copyrights in each file, but just can have a central COPYRIGHT file and save the work to maintain a per-file copyright. Anway, even though I don't agree with your reasoning, I certainly don't want to open a big discussion about this here. Thanks for explaining.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with everything here. Just tell me what, in your opinion, should be the copyright header, or if I can remove that completely? I must admit that I just copy/pasted the copyright notice from another file, trying to adhere to the code standards of this project, and not paying much attention to the header's content.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note I'm going to blast all headers to have consistent BSD license. I feel that the git history is best way to determine authorship. Adding a name to the license comment is very misleading/ambiguous sometimes. Did that person fix a typo or write most of it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall I wipe out the header from this file, then?