Skip to content
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

Experiment #3

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions experiment/tree/AbstractParseTreeVisitor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* [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.
*/

// ConvertTo-TS run at 2016-10-02T18:54:42.6538504-07:00

export abstract class AbstractParseTreeVisitor<Result> implements ParseTreeVisitor<Result> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ How would this be imported in another file, considering it's in a "tree" subfolder?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably easier for me to give you and example...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For code outside the runtime, you would use a non-relative module identifier. E.g.:

import {AbstractParseTreeVisitor} from 'antlr4/tree';

We also have the option to define a façade, by writing something like the index.ts files, that re-exports all public types in a flattened form, so that this could work:

import {AbstractParseTreeVisitor} from 'antlr4';

I think I would prefer the later, but not too strongly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the name antlr4 above might be antlr4ts given the current module. We stake-out the ground for a given name by registering it on npmjs.org (as I understand it.).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Eric has already register antlr4.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

antlr4ts makes sense to me

/**
* {@inheritDoc}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Is there any specific syntax/semantics for TypeScript documentation comments, or are they just plain text?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To typescript itself, it's plain text, but I think there are tools for Javadoc like processing...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a special-case for comments starting with /// <reference... , but it's not something you need to worry about just now.

*
* <p>The default implementation calls {@link ParseTree#accept} on the
* specified tree.</p>
*/
/*@Override*/
visit(/*@NotNull*/ tree: ParseTree): Result {
Copy link
Member

@sharwell sharwell Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Could we get away with @NotNull (or @notnull) as a decorator here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is experimental support for decorators. We could define a module that defines dummy decorators and leave them in-place. Is that would you are thinking about?

Copy link
Member

@sharwell sharwell Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭 It'd be nice to leave them in to start with. We can always pull them out later.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easy to change in my script.

return tree.accept(this);
}

/**
* {@inheritDoc}
*
* <p>The default implementation initializes the aggregate result to
* {@link #defaultResult defaultResult()}. Before visiting each child, it
* calls {@link #shouldVisitNextChild shouldVisitNextChild}; if the result
* is {@code false} no more children are visited and the current aggregate
* result is returned. After visiting a child, the aggregate result is
* updated by calling {@link #aggregateResult aggregateResult} with the
* previous aggregate result and the result of visiting the child.</p>
*
* <p>The default implementation is not safe for use in visitors that modify
* the tree structure. Visitors that modify the tree should override this
* method to behave properly in respect to the specific algorithm in use.</p>
*/
/*@Override*/
visitChildren(/*@NotNull*/ node: RuleNode): Result {
let result: Result = defaultResult();
let n: number = node.getChildCount();
for (let i=0; i<n; i++) {
if (!shouldVisitNextChild(node, result)) {
break;
}

let c: ParseTree = node.getChild(i);
let childResult: Result = c.accept(this);
result = aggregateResult(result, childResult);
}

return result;
}

/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of
* {@link #defaultResult defaultResult}.</p>
*/
/*@Override*/
visitTerminal(/*@NotNull*/ node: TerminalNode): Result {
return defaultResult();
}

/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of
* {@link #defaultResult defaultResult}.</p>
*/
/*@Override*/
visitErrorNode(/*@NotNull*/ node: ErrorNode): Result {
return defaultResult();
}

/**
* Gets the default value returned by visitor methods. This value is
* returned by the default implementations of
* {@link #visitTerminal visitTerminal}, {@link #visitErrorNode visitErrorNode}.
* The default implementation of {@link #visitChildren visitChildren}
* initializes its aggregate result to this value.
*
* <p>The base implementation returns {@code null}.</p>
*
* @return The default value returned by visitor methods.
*/
protected defaultResult(): Result {
return null;
}

/**
* Aggregates the results of visiting multiple children of a node. After
* either all children are visited or {@link #shouldVisitNextChild} returns
* {@code false}, the aggregate value is returned as the result of
* {@link #visitChildren}.
*
* <p>The default implementation returns {@code nextResult}, meaning
* {@link #visitChildren} will return the result of the last child visited
* (or return the initial value if the node has no children).</p>
*
* @param aggregate The previous aggregate value. In the default
* implementation, the aggregate value is initialized to
* {@link #defaultResult}, which is passed as the {@code aggregate} argument
* to this method after the first child node is visited.
* @param nextResult The result of the immediately preceeding call to visit
* a child node.
*
* @return The updated aggregate result.
*/
protected aggregateResult(aggregate: Result, nextResult: Result): Result {
return nextResult;
}

/**
* This method is called after visiting each child in
* {@link #visitChildren}. This method is first called before the first
* child is visited; at that point {@code currentResult} will be the initial
* value (in the default implementation, the initial value is returned by a
* call to {@link #defaultResult}. This method is not called after the last
* child is visited.
*
* <p>The default implementation always returns {@code true}, indicating that
* {@code visitChildren} should only return after all children are visited.
* One reason to override this method is to provide a "short circuit"
* evaluation option for situations where the result of visiting a single
* child has the potential to determine the result of the visit operation as
* a whole.</p>
*
* @param node The {@link RuleNode} whose children are currently being
* visited.
* @param currentResult The current aggregate result of the children visited
* to the current point.
*
* @return {@code true} to continue visiting children. Otherwise return
* {@code false} to stop visiting children and immediately return the
* current aggregate result from {@link #visitChildren}.
*/
protected shouldVisitNextChild(/*@NotNull*/ node: RuleNode, currentResult: Result): boolean {
return true;
}

}
34 changes: 34 additions & 0 deletions experiment/tree/ErrorNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* [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.
*/

// ConvertTo-TS run at 2016-10-02T18:54:42.7458518-07:00

export interface ErrorNode extends TerminalNode {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ In ANTLR, this is essentially a marker interface. Is it possible to perform a type check in TypeScript so you know if an object implements a marker interface, even if it has no members?

Copy link
Collaborator Author

@BurtHarris BurtHarris Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No!. Interfaces in typescript have no existence at runtime. For cases like this we will probably want to change an interface into an abstract class, so that we can use the instanceof operator.

}
49 changes: 49 additions & 0 deletions experiment/tree/ErrorNodeImpl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* [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.
*/

// ConvertTo-TS run at 2016-10-02T18:54:42.8098507-07:00

/** Represents a token that was consumed during resynchronization
* rather than during a valid match operation. For example,
* we will create this kind of a node during single token insertion
* and deletion as well as during "consume until error recovery set"
* upon no viable alternative exceptions.
*/
export class ErrorNodeImpl extends TerminalNodeImpl implements ErrorNode
{
constructor(token: Token) {
super(token);
}

/*@Override*/
accept<T>(visitor: ParseTreeVisitor<? extends T>): T {
return visitor.visitErrorNode(this);
}
}
60 changes: 60 additions & 0 deletions experiment/tree/ParseTree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* [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.
*/

// ConvertTo-TS run at 2016-10-02T18:54:42.9018502-07:00

/** An interface to access the tree of {@link RuleContext} objects created
* during a parse that makes the data structure look like a simple parse tree.
* This node represents both internal nodes, rule invocations,
* and leaf nodes, token matches.
*
* <p>The payload is either a {@link Token} or a {@link RuleContext} object.</p>
*/
export interface ParseTree extends SyntaxTree {
// the following methods narrow the return type; they are not additional methods
/*@Override*/
getParent(): ParseTree;
Copy link
Member

@sharwell sharwell Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Should this be:

readonly parent: ParseTree;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be... I was looking to make the minimum source change necessary, rather than impose TypeScript style on the code, at least at first...

/*@Override*/
getChild(i: number): ParseTree;

/** The {@link ParseTreeVisitor} needs a double dispatch method. */
accept<T>(visitor: ParseTreeVisitor<? extends T>): T;

/** Return the combined text of all leaf nodes. Does not get any
* off-channel tokens (if any) so won't return whitespace and
* comments if they are sent to parser on hidden channel.
*/
getText(): string;

/** Specialize toStringTree so that it can print out more information
* based upon the parser.
*/
toStringTree(parser: Parser): string;
}
49 changes: 49 additions & 0 deletions experiment/tree/ParseTreeListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* [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.
*/

// ConvertTo-TS run at 2016-10-02T18:54:42.9738510-07:00

/** This interface describes the minimal core of methods triggered
* by {@link ParseTreeWalker}. E.g.,
*
* ParseTreeWalker walker = new ParseTreeWalker();
* walker.walk(myParseTreeListener, myParseTree); <-- triggers events in your listener
*
* If you want to trigger events in multiple listeners during a single
* tree walk, you can use the ParseTreeDispatcher object available at
*
* https://github.com/antlr/antlr4/issues/841
*/
export interface ParseTreeListener {
visitTerminal(/*@NotNull*/ node: TerminalNode): void;
visitErrorNode(/*@NotNull*/ node: ErrorNode): void;
enterEveryRule(/*@NotNull*/ ctx: ParserRuleContext): void;
exitEveryRule(/*@NotNull*/ ctx: ParserRuleContext): void;
}
Loading