blob: a02a085608260452a9c998657af10583459c2e59 [file] [log] [blame]
% Parsing and Program Analysis
\section{Parsing}
Before any program analysis can be done, the source code of the Fortran program
has to be parsed. Photran provides support for both fixed-form (Fortran 77) and
free-form Fortran (Fortran 90 \& 95) source code. The parser in Photran is
generated using the Ludwig parser/AST generator by Jeff Overbey. It is based on
the \emph{fortran2003.bnf} grammar file.
Figure~\ref{fig:images_parser_chain} shows the lexer \& parser tool chain in
Photran. Preliminary support for (\texttt{INCLUDE} directives) has also been
implemented.
\begin{image}
\centering
\includegraphics[height=3in]{images/parser_chain.png}
\caption{Photran preprocessor/lexer/parser chain}
\label{fig:images_parser_chain}
\end{image}
\section{Virtual Program Graph}
\label{sec:virtual_program_graph}
% I can't seem to get the cedilla fa\c{c}ade to render in my version of LaTeX
In Photran, it is \emph{almost} never necessary to call the lexer, parser, or
analysis components directly. Instead, Photran uses a \textbf{virtual program
graph} (VPG), which provides the facade of a whole-program abstract syntax tree
(AST) with embedded analysis information. In general, program analysis should be
performed through the Photran VPG.
An overview of VPGs is available at the following link:
\url{http://jeff.over.bz/software/vpg/doc/}. It provides the background
necessary for the remaining sections of this chapter.
\subsection{Using the Photran VPG}
\subsubsection{Acquiring and Releasing Translation Units}
% TODO Make sure that this fits nicely into the page
\texttt{PhotranVPG} is a \emph{singleton} object responsible for constructing
ASTs for Fortran source code. ASTs are retrieved by invoking either of these
methods:
\begin{code}
\begin{lstlisting}[numbers=none]
public IFortranAST acquireTransientAST(IFile file)
public IFortranAST acquirePermanentAST(IFile file)
\end{lstlisting}
\caption{Acquiring the Fortran AST}
\end{code}
\vspace{-0.15in}
The returned object is an IFortranAST, an object which has a method for
returning the root node of the AST as well as methods to quickly locate tokens
in the AST by offset or line information. A \emph{transient AST} can be garbage
collected as soon as references to any of its nodes disappear. A \emph{permanent
AST} will be explicitly kept in memory until a call is made to either of the
following methods:
\begin{code}
\begin{lstlisting}[numbers=none]
public void releaseAST(IFile file)
public void releaseAllASTs()
\end{lstlisting}
\caption{Releasing the Fortran AST}
\end{code}
Often, it is better to acquire a transient AST and rely on the garbage collector
to reclaim the memory once we are done using it. However, there are times when
acquiring a permanent AST would be more beneficial performance-wise. For
instance, if we will be using the same AST multiple times during a refactoring,
it would be better to just acquire a permanent AST. This prevents the garbage
collector from reclaiming the memory midway through the refactoring once all
references to the AST have been invalidated. While it is always possible to
reacquire the same AST, doing so can be an expensive operation since it requires
\emph{lexing}, \emph{parsing} \textbf{and} finally \emph{reconstructing} the AST
from scratch.
Only one AST for a particular file is in memory at any particular point in time,
so successive requests for the same \texttt{IFile} will return the same
(pointer-identical) AST until the AST is released (permanent) or garbage
collected (transient).
\subsubsection{Caveat}
It is important to note that, because \texttt{PhotranVPG} is a singleton object,
one must be careful about accessing it from multiple threads. Most of the time,
when an AST is required, it will be from an action contributed to the Fortran
editor; in this case, the action will usually be a descendant of
\texttt{FortranEditorActionDelegate}, and synchronization will be handled
automatically. For instance, all refactoring actions in Photran are descendants
of \texttt{FortranEditorActionDelegate} and their accesses to
\texttt{PhotranVPG} are being synchronized automatically.
Otherwise, the thread must either be scheduled using a
\texttt{VPGSchedulingRule} or it must lock the entire workspace . See
\texttt{EclipseVPG\#queueJobToEnsureVPGIsUpToDate} as an example on how to use
the \texttt{VPGSchedulingRule} and \texttt{FortranEditorActionDelegate\#run} as
an example of how to lock the entire workspace.
As a guideline, contributors who are interested in accessing the VPG should
consider structuring their contributions as descendants of
\texttt{FortranEditorActionDelegate} since that is the simplest mechanism (all
synchronization is already taken care of automatically). However, if such an
approach is not feasible, then they should consider using
\texttt{VPGSchedulingRule} before resorting to locking the entire workspace.
\subsection{The Program Representation: IFortranAST}
The \texttt{acquireTransientAST} and \texttt{acquirePermanentAST} methods return
an object implementing \texttt{IFortranAST}. Listing~\ref{lst:ifortranast} shows
the methods in IFortranAST.
\begin{code}
\begin{lstlisting}[firstnumber=25]
public interface IFortranAST extends Iterable<Token>
{
///////////////////////////////////////////////////////////////////////////
// Visitor Support
///////////////////////////////////////////////////////////////////////////
public void accept(IASTVisitor visitor);
///////////////////////////////////////////////////////////////////////////
// Other Methods
///////////////////////////////////////////////////////////////////////////
public ASTExecutableProgramNode getRoot();
public Iterator<Token> iterator();
public Token findTokenByStreamOffsetLength(int offset, int length);
public Token findFirstTokenOnLine(int line);
public Token findTokenByFileOffsetLength(IFile file, int offset, int length);
}
\end{lstlisting}
\caption{\texttt{IFortranAST} (see IFortranAST.java)}
\label{lst:ifortranast}
\end{code}
The \texttt{getRoot} method returns the root of the AST, while the
\texttt{find...} methods provide efficient means to search for tokens based
on their lexical positioning in the source code.
The \texttt{accept} method allows an external visitor to traverse the AST. This
method is usually used when it is necessary to ``collect'' information about
certain nodes. For more information see Section~\ref{sec:ast_structure} on what
nodes can be visited.
Because \texttt{IFortranAST} extends the \texttt{Iterable} interface, it is
possible to use the \emph{foreach} loop to conveniently iterate through all the
tokens in the AST e.g. \\ \lstinline!for (Token token : new IterableWrapper<Token>(ast))!
\section{AST Structure}
\label{sec:ast_structure}
Photran's (rewritable) AST is generated along with the parser, so the structure
of an AST is determined by the structure of the parsing grammar (see the
\emph{fortran2003.bnf} file). The generated classes are located in the
\texttt{org.eclipse.photran.internal.core.parser} package in the
\texttt{org.eclipse.photran.core.vpg} project. The easiest way to visualize the
structure of a particular file's AST is to view it in the Outline view (see
Section~\ref{sec:how_to_get_acquainted_with_the_program_representation}).
However determining all possible ASTs for a particular construct requires
scrutinizing the parsing grammar file.
\subsection{Ordinary AST Nodes}
\label{sub:ordinary_ast_nodes}
Generally speaking, there is one AST node for each nonterminal in the grammar
and one accessor method for each symbol on its right-hand side (unless the
symbol name is prefixed with a hyphen, in which case it is omitted). For
example, the following specification\footnote{All grammar
specifications are taken from the \emph{fortran2003.bnf} file. The \# RXXX number
provides a reference to the actual specification in the grammar file.}
{\footnotesize\begin{verbatim}
# R533
<DataStmtSet> ::= <DataStmtObjectList> -:T_SLASH <DataStmtValueList> -:T_SLASH
\end{verbatim}}
generates the AST node class \texttt{ASTDataStmtSetNode} shown in
Listing~\ref{lst:astdatastmtsetnode_api}. Notice the \emph{presence} of the
\texttt{getDataStmtObjectList} and \texttt{getDataStmtValueList} getters methods
and the \emph{absence} of any method for accessing T\_SLASH.
\shabox{The convention is to generate a class with the name
\texttt{\color{LightMagenta}AST}$<$nonterminal
name$>$\texttt{\color{LightMagenta}Node} that extends \texttt{ASTNode}. For
instance \# R533 will generate the
\texttt{{\color{LightMagenta}AST}DataStmtSet{\color{LightMagenta}Node}} class.}
The following sections describe additional annotations that can be used to
modify the standard convention when necessary. These annotations are not
considered part of the standard BNF notation but they are supported by the
underlying Ludwig parser generator.
\begin{code}
\begin{lstlisting}
public class ASTDataStmtSetNode extends ASTNode
{
public IASTListNode<IDataStmtObject> getDataStmtObjectList() {...}
public void setDataStmtObjectList(IASTListNode<IDataStmtObject> newValue) {...}
public IASTListNode<ASTDataStmtValueNode> getDataStmtValueList() {...}
public void setDataStmtValueList(IASTListNode<ASTDataStmtValueNode> newValue) {...}
...
}
\end{lstlisting}
\caption{\texttt{ASTDataStmtSetNode} generated from \# R533}
\label{lst:astdatastmtsetnode_api}
\end{code}
\subsubsection{Annotation \#1: \texttt{(list)}}
Recursive productions are treated specially, since they are used frequently to
express lists in the grammar. The recursive member is labeled in the grammar
with the \texttt{(list)} annotation. For example, the following specification
{\footnotesize\begin{verbatim}
# R538
(list):<DataStmtValueList> ::=
| <DataStmtValue>
| <DataStmtValueList> -:T_COMMA <DataStmtValue>
\end{verbatim}}
means that the AST will contain an object of type
\texttt{List$<$ASTDataStmtValueNode$>$} whenever a \verb!<DataStmtValueList>!
appears in the grammar. For instance, \# R533 (just described in the previous
section) uses the \texttt{DataStmtValueList} construct. Notice in
Listing~\ref{lst:astdatastmtsetnode_api} that the return type of
\texttt{getDataStmtValueList} is a \texttt{List}.
Putting an object that implements the \texttt{java.util.List} into the tree
(rather than having a chain of nodes) makes it easier to iterate through the
list, determine its size and insert new child nodes.
\subsubsection{Annotation \#2: \texttt{(superclass)}}
The \texttt{(superclass)} annotation is used to create an interface that is
implemented by all symbols on the right-hand side of the specification will
implement. For example, the following specifications
{\footnotesize\begin{verbatim}
# R207
(superclass):<DeclarationConstruct> ::=
| <DerivedTypeDef>
| <InterfaceBlock>
| <TypeDeclarationStmt>
| <SpecificationStmt>
...
# R214
(superclass):<SpecificationStmt> ::=
| <AccessStmt>
| <AllocatableStmt>
| <CommonStmt>
| <DataStmt>
| <DimensionStmt>
| <EquivalenceStmt>
| <ExternalStmt>
| <IntentStmt>
| <IntrinsicStmt>
| <NamelistStmt>
| <OptionalStmt>
| <PointerStmt>
| <SaveStmt>
| <TargetStmt>
| <UnprocessedIncludeStmt>
\end{verbatim}}
mean that an \textbf{interface} -- not a class -- named
\texttt{ISpecificationStmt} will be generated for \# R214, and
\texttt{ASTAccessStmtNode}, \texttt{ASTAllocatableStmtNode},
\texttt{ASTCommonStmtNode}, etc will implement that interface. In addition,
because \verb!<SpecificationStmt>! is used inside \# R207 which also uses the
\texttt{(superclass):} annotation, \texttt{ISpecificationStmt} also extends the
\texttt{IDeclarationConstruct} interface from \# R207 i.e.
\begin{lstlisting}[numbers=none]
public interface ISpecificationStmt extends IASTNode, IDeclarationConstruct
\end{lstlisting}
So, it is possible for an AST node to implement multiple interfaces based on the
specifications in the grammar.
Using the \texttt{(superclass)} annotation gives those nonterminals in \# R214
nodes a common type; most notably, a \texttt{Visitor} can override the
\texttt{visit(ISpecificationStmt)} method to treat all three node types
uniformly.
\subsubsection{Annotation \#3: \texttt{(bool)}}
The \texttt{(bool)} annotation indicates that an accessor method will return a
\lstinline!boolean! rather than an actual AST node. For example, the following
specification
{\footnotesize\begin{verbatim}
# R511
<AccessSpec> ::=
| isPublic(bool):T_PUBLIC
| isPrivate(bool):T_PRIVATE
\end{verbatim}}
will generate the \texttt{ASTAccessSpecNode} class as shown in Listing~\ref{lst:astaccessspecnode_api}.
\begin{code}
\begin{lstlisting}
public class ASTAccessSpecNode extends ASTNode
{
// in ASTAccessSpecNode
Token isPrivate;
// in ASTAccessSpecNode
Token isPublic;
public boolean isPrivate() {...}
public void setIsPrivate(Token newValue) {...}
public boolean isPublic() {...}
public void setIsPublic(Token newValue) {...}
...
}
\end{lstlisting}
\caption{ASTAccessSpecNode generated from \# R511}
\label{lst:astaccessspecnode_api}
\end{code}
Notice on lines 8 \& 12 that the methods return \lstinline!boolean! values
instead of \texttt{ASTNode}s. The \lstinline!boolean! values are usually used to
test the presence of that particular \texttt{ASTNode} in the source code.
\subsubsection{Annotation \#4: Labels}
Specification \# R511 also illustrates the use of \emph{labels} in the grammar
file: \verb!isPublic(bool):T_PUBLIC! results in a method called
\texttt{isPublic} instead of \verb!getT_PUBLIC!. The use of labels can greatly
enhance the readability of the program by making its intent clearer.
\subsubsection{Annotation \#5: \texttt{(inline)}}
Consider the following specifications for a main program in Fortran:
{\footnotesize\begin{verbatim}
# R1101
<MainProgram> ::=
| <MainRange>
| <ProgramStmt> <MainRange>
<MainRange> ::=
| <Body> <EndProgramStmt>
| <BodyPlusInternals> <EndProgramStmt>
|
\end{verbatim}}
From the standpoint of a typical Fortran programmer, a main program consists of
a Program statement, a body (list of statements), perhaps some internal
subprograms, and an End Program statement. This does not match the definition of
a \verb!<MainProgram>! in the parsing grammar above: \verb!<Body>! and
\verb!<EndProgStmt>! are relegated to a separate \verb!<MainRange>! nonterminal.
The solution is to label the MainRange nonterminal with the \texttt{(inline)} annotation, indicating that it is to be in-lined:
{\footnotesize\begin{verbatim}
# R1101
(customsuperclass=ScopingNode):<MainProgram> ::=
| (inline):<MainRange>
| <ProgramStmt> (inline):<MainRange>
<MainRange> ::=
| <Body> <EndProgramStmt>
| (inline):<BodyPlusInternals> <EndProgramStmt>
|
\end{verbatim}}
This means that accessor methods that would otherwise be in a separate
\texttt{ASTMainRangeNode} class will be placed in the
\texttt{ASTMainProgramNode} class instead.
Listing~\ref{lst:astmainprogramnode_api} shows that the accessors that were
previously in \texttt{ASTMainRangeNode} have been in-lined to
\texttt{ASTMainProgramNode}. Now there is no longer any need for a
\texttt{ASTMainRangeNode} class.
\begin{code}
\begin{lstlisting}
public class ASTMainProgramNode extends ScopingNode implements IProgramUnit
{
public ASTProgramStmtNode getProgramStmt()
public void setProgramStmt(ASTProgramStmtNode newValue)
public IASTListNode<IBodyConstruct> getBody()
public void setBody(IASTListNode<IBodyConstruct> newValue)
public ASTContainsStmtNode getContainsStmt()
public void setContainsStmt(ASTContainsStmtNode newValue)
public IASTListNode<IInternalSubprogram> getInternalSubprograms()
public void setInternalSubprograms(IASTListNode<IInternalSubprogram> newValue)
public ASTEndProgramStmtNode getEndProgramStmt()
public void setEndProgramStmt(ASTEndProgramStmtNode newValue)
...
}
\end{lstlisting}
\caption{\texttt{ASTMainProgramNode} generated from \# R1101}
\label{lst:astmainprogramnode_api}
\end{code}
\subsubsection{Annotation \#6: \texttt{(customsuperclass=*)}}
Specification \# R1101 in the previous section also illustrates the use of the
\\ \texttt{(customsuperclass=ScopingNode)} annotation. This makes
\texttt{ScopingNode} the parent of the \texttt{ASTMainProgramNode} class. Note
that \texttt{ScopingNode} (or whichever custom super class is chosen) has to be
a descendant of \texttt{ASTNode} because every node in the AST has to be of that
type (either directly or as a descendant).
The \texttt{(customsuperclass=*)} annotation is a useful technique for
delegating external methods that cannot be expressed through the grammar BNF
file into a separate hand-coded class while still having the benefits of an
auto-generated parser and AST.
\subsection{Tokens}
\label{sub:tokens}
\texttt{Token}s form the leaves of the AST. They record, among other things,
\begin{itemize}
\item The terminal symbol in the grammar that the token is an instance of (\texttt{getTerminal()})
\item The actual text of the token (\texttt{getText()})
\item The line, column, offset, and length of the token text in the source file (\texttt{getLine(), getCol(), getFileOffset(), getLength()})
\end{itemize}
Most of the remaining fields are used internally for refactoring.
\subsection{Fortran Program AST Example}
The previous sections describe the conventions and additional annotations that
are used to construct the AST nodes. While the conventions and annotations
themselves are simple, the Fortran grammar is extremely complicated and contains
hundreds of rules. Even the simplest Fortran program might contain a very
complicated AST. For instance this simple Fortran program: \\
\begin{lstlisting}[language=Fortran, frame=lines]
program main
integer a
end
\end{lstlisting}
generates the AST shown in Figure~\ref{fig:simple_fortran_ast}. As an exercise,
the reader is encouraged to derive the structure of the AST from the grammar
specifications in the \emph{fortran2003.bnf} file beginning with \# R201,
\verb!<ExecutableProgram>!.
%Moreover, modifying our previous program slightly to contain an array as shown
%below, causes the AST structure to become extremely complicated. The reader is
%encouraged to create a file containing this program and view the resulting AST
%in the Outline View in Photran. Notice how the \verb!(5)! expression for
%specifying the dimension of the array requires building up an entire hierarchy
%of \texttt{ASTLevel5ExprNode}, \texttt{ASTLevel4ExprNode},
%\texttt{ASTLevel3ExprNode}, \ldots \\
%
%\begin{lstlisting}[language=Fortran, frame=lines]
%program main
% integer a(5) ! This declares an array of 5 integers
%end
%\end{lstlisting}
\begin{image}
\centering
\includegraphics[height=4in]{images/simple_fortran_AST.png}
\caption{AST for simple Fortran program as viewed through the Outline View}
\label{fig:simple_fortran_ast}
\end{image}
Fortunately, it is not necessary to know every specification in the grammar. For
most refactoring and program analysis tasks, it is sufficient to rely on the
information that the VPG provides. If that is insufficient, then it is usually
enough to construct a Visitor to visit \emph{only} the nodes of interest and
``collect'' the information that is required.
\section{AST Structure for DO-Loops}
Due to a deficiency in the parser, DO-constructs are not recognized as a single
construct; DO and END DO statements are recognized as ordinary statements
alongside the statements comprising their body. There is a package in the
core.vpg plug-in called org.eclipse.photran.internal.core.analysis.loops which
provides machinery to fix this, giving DO-loops a ``proper'' AST structure.
If you call \texttt{LoopReplacer.replaceAllLoopsIn(ast)}, it will identify all
of the new-style DO-loops and change them to \texttt{ASTProperLoopConstructNode}s,
which a more natural structure, with a loop header, body, and END DO statement.
Once this is done, visitors must be implemented by subclassing one of the
Visitor classes \emph{in the org.eclipse.photran.internal.core.analysis.loops
package;} these have a callback method to handle
\texttt{ASTProperLoopConstructNode}s.
\section{Scope and Binding Analysis}
Currently, the only semantic analysis performed by Photran is binding analysis:
mapping \emph{identifiers} to their \emph{declarations}. Compilers usually do
this using symbol tables but Photran uses a more IDE/refactoring-based approach.
Certain nodes in a Fortran AST represent a lexical scope. All of these nodes are
declared as subclasses of \texttt{ScopingNode}:
\begin{itemize}
\item ASTBlockDataSubprogramNode
\item ASTDerivedTypeDefNode
\item ASTExecutableProgramNode
\item ASTFunctionSubprogramNode
\item ASTInterfaceBlockNode\footnote{An interface block defines a nested scope only if it is a named interface.Anonymous (unnamed) interfaces provide signatures for subprograms in their enclosing scope.}
\item ASTMainProgramNode
\item ASTModuleNode
\item ASTSubroutineSubprogramNode
\end{itemize}
Each of the subclasses of \texttt{ScopingNode} represents a scoping unit in
Fortran. The \texttt{ScopingNode} class has several public methods that provide
information about a scope. For example, one can retrieve a list of all of the
symbols declared in that scope; retrieve information about its
\texttt{IMPLICIT} specification; find its header statement (e.g. a
\texttt{FUNCTION} or \texttt{PROGRAM} statement); and so forth.
The enclosing scope of a \texttt{Token} can be retrieved by calling the
following method on the \texttt{Token} object:
\begin{lstlisting}[numbers=none]
public ScopingNode getEnclosingScope()
\end{lstlisting}
Identifier tokens (\texttt{Token}s for which \texttt{token.getTerminal() ==
Terminal.T\_IDENT}), which represent functions, variables, etc. in the Fortran
grammar, are \emph{bound} to a declaration\footnote{The introduction to VPGs
earlier in this chapter (URL above) provides an example visually.}. Although,
ideally, every identifier will be bound to exactly one declaration, this is not
always the case: the programmer may have written incorrect code, or Photran may
not have enough information to resolve the binding uniquely). So the
\texttt{resolveBinding} method returns a \emph{list} of \texttt{Definition}
objects:
\begin{lstlisting}[numbers=none]
public List<Definition> resolveBinding()
\end{lstlisting}
A \texttt{Definition} object contains many public methods which provide a wealth
of information. From a \texttt{Definition} object, it is possible to get a list
of all the references to a particular declaration (using
\texttt{findAllReferences}) and where that particular declaration is located in
the source code (using \texttt{getTokenRef}). Both of these methods return a
\texttt{PhotranTokenRef} object. See Section~\ref{sub:token_or_tokenref} for a
comparison between \texttt{Token} and \texttt{TokenRef}.
\subsection{Examples of Binding Analysis}
\subsubsection{Obtaining the \texttt{Definition} of a variable}
If you have a reference to the \texttt{Token} object of that variable (for
instance through iterating over all \texttt{Tokens} in the current Fortran AST)
then use:
\begin{lstlisting}[numbers=none, frame=lines]
// myToken is the reference to that variable
List<Definition> bindings = myToken.resolveBinding();
if(bindings.size() == 0)
throw new Exception(myToken.getText() + " is not declared");
else if (bindings.size() > 1)
throw new Exception(myToken.getText() + " is an ambiguous reference");
Definition definition = bindings.get(0);
\end{lstlisting}
If you do \textbf{not} have a reference to a \texttt{Token} but you know the
name of the identifier, you can first construct a \emph{hypothetical}
\texttt{Token} representing an identifier and search for that in a
\emph{particular} \texttt{ScopingNode} (possibly obtained by calling the static
method \texttt{ScopingNode.getEnclosingScope(IASTNode node)}).
\\
\begin{lstlisting}[numbers=none, frame=lines]
Token myToken = new Token(Terminal.T_IDENT, "myNameOfIdentifier");
List<PhotranTokenRef> definitions = myScopingNode.manuallyResolve(myToken);
\end{lstlisting}
If you want to search for the identifier in \textbf{all} \texttt{ScopingNodes}
for the current source file, then retrieve all the \texttt{ScopingNodes} and
manually iterate through each one. Remember that the root of the AST is a
\texttt{ScopingNode} and you may obtain the root of the AST through the
\texttt{getRoot} method declared in \texttt{IFortranAST}.
\\
\begin{lstlisting}[numbers=none, frame=lines]
List<ScopingNode> scopes = myRoot.getAllContainedScopes();
for (ScopingNode scopingNode : scopes)
{
// search through each ScopingNode
}
\end{lstlisting}
\subsubsection{Examples in \texttt{FortranEditorASTActionDelegate} subclasses}
The following subclasses of \texttt{FortranEditorASTActionDelegate} all contain short working examples of how to use the binding analysis API in Photran:
\begin{itemize}
\item DisplaySymbolTable
\item FindAllDeclarationsInScope
\item OpenDeclaration
\item SelectEnclosingScope
\end{itemize}
\section{How to Get Acquainted with the Program Representation}
\label{sec:how_to_get_acquainted_with_the_program_representation}
\emph{All these features work on \textbf{Fortran projects}. A new Fortran
project can be created via File $>$ New $>$ Project\dots $>$ Fortran $>$ Fortran Project. These
features do not work on individual Fortran source files.}
\subsection{Visualizing ASTs}
Photran can display ASTs in place of the ordinary Outline view.
This behavior can be enabled from the Fortran workspace preferences:
\begin{itemize}
\item Click on Window $>$ Preferences in Windows/Linux, or Eclipse $>$ Preferences in Mac OS X.
\item Select ``Fortran'' on the left hand side of the preference dialog (do not expand it).
\item Select ``(Debugging) Show entire parse tree rather than Outline view''
\end{itemize}
Clicking on an AST \texttt{node}Token in the Outline view will move the cursor
to that construct's position in the source file.
\subsection{Visually Resolving Bindings}
This feature is disabled by default since it requires performing an update on
the VPG database each time the file is saved -- an operation that could be
expensive for larger files. To enable this feature, right-click on the current
Fortran project folder (\textbf{not} the individual Fortran source file) in the
Fortran Projects View and select ``Properties''. In the dialog that pops-up,
navigate to Fortran General $>$ Analysis/Refactoring. Select the ``Enable
Fortran Declaration view'' checkbox.
Then, in a Fortran editor, click on an identifier (position the cursor over
it), and press F3 (or click Navigate $>$ Open Declaration, or right-click and
choose Open Declaration.) The binding will be resolved and the declaration
highlighted. If there are multiple bindings, a pop-up window will open and one
can be selected. If the identifier is bound to a declaration in a module defined
in a different file, an editor will be opened on that file.
\subsection{Visualizing Enclosing Scopes}
Click on any token in the Fortran editor, and click Refactor $>$ (Debugging) $>$
Select Enclosing Scope. The entire range of source text for that token's
enclosing \texttt{ScopingNode} will be highlighted.
\subsection{Visualizing Definitions}
Open a file in the Fortran editor, and click Refactor $>$ (Debugging) $>$
Display Symbol Table for Current File. Indentation shows scope nesting, and each
line summarizes the information in a \texttt{Definition} object.