| |
|
| java.lang.Object xtc.tree.Utility xtc.parser.Analyzer
Analyzer | public class Analyzer extends Utility (Code) | | Utility for analyzing and modifying grammars. This class provides
the following functionality:
- A mapping from nonterminals to productions, which is
initialized through
Analyzer.init(Grammar) and accessed through
Analyzer.isDefined(NonTerminal) and
Analyzer.lookup(NonTerminal) .
- The set of top-level nonterminals, which is accessed through
Analyzer.isTopLevel(NonTerminal) .
- Methods to start
Analyzer.process processing a production and
to
Analyzer.current determine the current production.
- A working set, marked set, and processed set to determine
properties of productions. The idea behind these three sets is
that the working set keeps track of all productions during an
analysis pass and is used to prevent infinite recursion, the marked
set tracks the productions having the property, and the processed
set (which is a superset of the marked set) tracks the analyzed
productions. The working set is accessed through
Analyzer.workingOn(NonTerminal) ,
Analyzer.notWorkingOn(NonTerminal) ,
Analyzer.isBeingWorkedOn(NonTerminal) , and
Analyzer.working() . The
marked set is accessed through
Analyzer.mark(NonTerminal) ,
Analyzer.unmark(NonTerminal) ,
Analyzer.isMarked(NonTerminal) , and
Analyzer.marked() . Finally, the processed set is accessed through
Analyzer.processed(NonTerminal) and
Analyzer.isProcessed(NonTerminal) .
- Methods to add and remove productions from a grammar. New
productions are prepared for addition through
Analyzer.add(Production) and committed to the grammar through
Analyzer.addNewProductionsAt(int) . Existing productions are removed
through
Analyzer.remove(Production) .
- A set of methods for creating temporary variable names and
nonterminals for new productions:
Analyzer.variable() ,
Analyzer.choice() ,
Analyzer.star() ,
Analyzer.plus() ,
Analyzer.option() ,
and
Analyzer.shared() .
- A method to
Analyzer.strip(Element) strip unnecessary ordered
choices and sequences from an element.
- A method to test whether an element
Analyzer.matchesEmpty(Element) matches the empty input .
- A method to
Analyzer.copy(Element) copy an element.
- A set of methods for optimizing sequences that start with
terminals through character switches:
Analyzer.hasTerminalPrefix(Sequence) ,
Analyzer.normalize(Sequence) , and
Analyzer.join(Sequence,Element) .
- A method to
Analyzer.matchingText(Element) get the text of an
element.
- A method to
Analyzer.bind(Sequence) add bindings to a
sequence.
To utilize this analyzer utility for a given grammar, the utility
must be
Analyzer.init initialized(Grammar) with the grammar, and
each production must be
Analyzer.process processed with the
utility. Furthermore, new productions must be added through
Analyzer.add(Production) and obsolete productions must be removed through
Analyzer.remove(Production) .
The analyzer utility tracks the current grammar so that it
need not recreate its internal state (notably, the mapping from
nonterminals to productions) as long as the same analyzer utility
is used across different visitors.
author: Robert Grimm version: $Revision: 1.2 $ |
Field Summary | |
final public static String | CHOICE The suffix for nonterminals representing choices. | final public static int | MAX_COUNT The maximum character count for turning character classes into
character switches. | final public static String | OPTION The suffix for nonterminals representing options. | final public static String | PLUS The suffix for nonterminals representing one or more
repetitions. | final public static String | SEPARATOR The separator character for creating new nonterminals, which
should be illegal in regular variable or nonterminal names. | final public static String | SHARED The base name for nonterminals representing shared productions. | final public static String | STAR The suffix for nonterminals representing zero or more
repetitions. | final public static String | VARIABLE The base name for temporary variables. | protected int | choiceCount The count of lifted choices for the current production. | protected Grammar | grammar The current grammar. | protected int | optionCount The count of desugared options for the current production. | protected Production | pCurrent The current production. | protected Map | pMap The map from nonterminals to productions. | protected Set | pMarked The set of nonterminals corresponding to productions having
been marked. | protected List | pNew The list of newly added productions. | protected Set | pProcessed The set of nonterminals corresponding to productions having
been processed. | protected Set | pTop The set of top-level nonterminals. | protected Set | pWorking The set of nonterminals corresponding to productions currently
being processed. | protected int | plusCount The count of desugared plus repetitions for the current production. | protected int | sharedCount The count of shared productions. | protected int | starCount The count of desugared star repetitions for the current production. | protected int | varCount The count of temporary variables for the current production. | final protected Copier | xerox The element copier. |
Constructor Summary | |
public | Analyzer() Create a new analyzer utility. |
Method Summary | |
public void | add(Production p) Prepare the specified production for addition to the grammar.
This method adds the specified production to the list of newly
generated productions. | public int | addNewProductionsAt(int idx) Add the newly generated productions to the grammar itself. | public Binding | bind(Sequence s) Bind the elements in the specified sequence. | public NonTerminal | choice() Create a new nonterminal for a choice. | public Element | copy(Element e) Make a deep copy of the specified element.
Parameters: e - The element. | public Production | current() Get the production currently being processed. | public boolean | hasTerminalPrefix(Sequence s) Determine whether the specified sequence starts with terminals
that can be optimized. | public void | init(Grammar g) Initialize this analyzer for the specified grammar. | public boolean | isBeingWorkedOn(NonTerminal nt) Determine whether the specified nonterminal is being worked on.
Parameters: nt - The nonterminal. | public boolean | isDefined(NonTerminal nt) Determine whether the specified nonterminal is defined. | public boolean | isMarked(NonTerminal nt) Determine whether the specified nonterminal has been marked.
Parameters: nt - The nonterminal. | public boolean | isProcessed(NonTerminal nt) Determine whether the specified nonterminal has been processed.
Parameters: nt - The nonterminal. | public boolean | isTopLevel(NonTerminal nt) Determine whether the specified nonterminal is top-level.
Parameters: nt - The nonterminal. | public Element | join(Sequence source, Element target) Join the specified sequence with the specified element. | public Production | lookup(NonTerminal nt) Look up the production for the specified nonterminal.
Parameters: nt - The nonterminal. | public void | mark(NonTerminal nt) Mark the specified nonterminal. | public Set | marked() Get the set of marked nonterminals. | public boolean | matchesEmpty(Element e) Determine whether the specified element matches the empty input.
Note that this method assumes that nonterminals do not match the
empty input.
Parameters: e - The element. | public String | matchingText(Element e) Get the text matched by the specified element. | public Sequence | normalize(Sequence s) Normalize the specified sequence for
Analyzer.join(Sequence,Element) joining with other elements during
terminal optimization. | public void | notWorkingOn(NonTerminal nt) Set the status of the specified nonterminal as not being worked
on. | public NonTerminal | option() Create a new nonterminal for an option. | public NonTerminal | plus() Create a new nonterminal for one or more repetitions. | public void | process(Production p) Process the specified production. | public void | processed(NonTerminal nt) Set the status of the specified nonterminal as processed. | public void | remove(Production p) Prepare the specified production for removal from the grammar.
This method removes the specified production from the mapping
from nonterminals to productions and, if present, from the set of
top-level nonterminals. | public void | reset() Forcibly reset the analyzer utility. | public NonTerminal | shared() Create a new nonterminal for a shared production. | public NonTerminal | star() Create a new nonterminal for zero or more repetitions. | public void | startAdding() Clear the list of newly generated productions. | public Element | strip(Element e) Strip unnecessary ordered choices and sequences from the specified
element. | public void | unmark(NonTerminal nt) Unmark the specified nonterminal. | public String | variable() Create a new temporary variable. | public Set | working() Get the set of nonterminals being worked on. | public void | workingOn(NonTerminal nt) Set the status of the specified nonterminal as being worked on. |
CHOICE | final public static String CHOICE(Code) | | The suffix for nonterminals representing choices.
|
MAX_COUNT | final public static int MAX_COUNT(Code) | | The maximum character count for turning character classes into
character switches.
|
OPTION | final public static String OPTION(Code) | | The suffix for nonterminals representing options.
|
PLUS | final public static String PLUS(Code) | | The suffix for nonterminals representing one or more
repetitions.
|
SEPARATOR | final public static String SEPARATOR(Code) | | The separator character for creating new nonterminals, which
should be illegal in regular variable or nonterminal names.
|
SHARED | final public static String SHARED(Code) | | The base name for nonterminals representing shared productions.
|
STAR | final public static String STAR(Code) | | The suffix for nonterminals representing zero or more
repetitions.
|
VARIABLE | final public static String VARIABLE(Code) | | The base name for temporary variables.
|
choiceCount | protected int choiceCount(Code) | | The count of lifted choices for the current production.
|
optionCount | protected int optionCount(Code) | | The count of desugared options for the current production.
|
pMap | protected Map pMap(Code) | | The map from nonterminals to productions.
|
pMarked | protected Set pMarked(Code) | | The set of nonterminals corresponding to productions having
been marked.
|
pNew | protected List pNew(Code) | | The list of newly added productions.
|
pProcessed | protected Set pProcessed(Code) | | The set of nonterminals corresponding to productions having
been processed.
|
pTop | protected Set pTop(Code) | | The set of top-level nonterminals.
|
pWorking | protected Set pWorking(Code) | | The set of nonterminals corresponding to productions currently
being processed.
|
plusCount | protected int plusCount(Code) | | The count of desugared plus repetitions for the current production.
|
sharedCount | protected int sharedCount(Code) | | The count of shared productions.
|
starCount | protected int starCount(Code) | | The count of desugared star repetitions for the current production.
|
varCount | protected int varCount(Code) | | The count of temporary variables for the current production.
|
Analyzer | public Analyzer()(Code) | | Create a new analyzer utility.
|
add | public void add(Production p)(Code) | | Prepare the specified production for addition to the grammar.
This method adds the specified production to the list of newly
generated productions. It also adds the production to the map
from nonterminals to productions and marks it as
Constants.SYNTHETIC synthetic . However, addition is not
complete: the productions in the list of newly generated
productions still need to be added into the grammar itself. This
is typically done within the main loop iterating over a grammar's
productions and thus through a separate
Analyzer.addNewProductionsAt(int) method .
Parameters: p - The new production. |
addNewProductionsAt | public int addNewProductionsAt(int idx)(Code) | | Add the newly generated productions to the grammar itself. This
method adds the productions collected through
Analyzer.add(Production) add() into the current grammar at the specified
index of the grammar's list of productions.
Parameters: idx - The index into the grammar's list of productions. The number of productions added. |
bind | public Binding bind(Sequence s)(Code) | | Bind the elements in the specified sequence. This method
analyzes the specified sequence and, if necessary, adds in a
binding for the semantic value of the elements in the sequence.
If the sequence has more than one element to be bound, this
method returns null to indicate that we need to rely
on the
CodeGenerator.VALUE semantic value to capture the
sequence's value.
Parameters: s - The sequence to bind. The corresponding binding. |
choice | public NonTerminal choice()(Code) | | Create a new nonterminal for a choice.
The new nonterminal. |
copy | public Element copy(Element e)(Code) | | Make a deep copy of the specified element.
Parameters: e - The element. A deep copy. |
current | public Production current()(Code) | | Get the production currently being processed.
The current production. |
hasTerminalPrefix | public boolean hasTerminalPrefix(Sequence s)(Code) | | Determine whether the specified sequence starts with terminals
that can be optimized. This method returns true if
the terminals can be optimized through character switches.
Currently, this is only the case for character and string
literals.
Parameters: s - The sequence. true if the sequence starts with optimizableterminals. |
init | public void init(Grammar g)(Code) | | Initialize this analyzer for the specified grammar. This method
initializes the map from nonterminals to productions and the set
of top-level nonterminals. It also clears the sets of marked and
processed nonterminals. It should be called before iterating
over a grammar's productions.
Parameters: g - The grammar. |
isBeingWorkedOn | public boolean isBeingWorkedOn(NonTerminal nt)(Code) | | Determine whether the specified nonterminal is being worked on.
Parameters: nt - The nonterminal. true if the nonterminal is being workedon. |
isDefined | public boolean isDefined(NonTerminal nt)(Code) | | Determine whether the specified nonterminal is defined. A
nonterminal is defined if the current grammar contains a
production for that nonterminal.
Parameters: nt - The nonterminal. true if the nonterminal is defined. |
isMarked | public boolean isMarked(NonTerminal nt)(Code) | | Determine whether the specified nonterminal has been marked.
Parameters: nt - The nonterminal. true if the nonterminal has beenmarked. |
isProcessed | public boolean isProcessed(NonTerminal nt)(Code) | | Determine whether the specified nonterminal has been processed.
Parameters: nt - The nonterminal. true if the nonterminal has been processed. |
isTopLevel | public boolean isTopLevel(NonTerminal nt)(Code) | | Determine whether the specified nonterminal is top-level.
Parameters: nt - The nonterminal. true if the nonterminal is top-level. |
join | public Element join(Sequence source, Element target)(Code) | | Join the specified sequence with the specified element. Note
that the specified sequence must have been
Analyzer.normalize(Sequence) normalized . Further note that the combined
element is guaranteed to either be a sequence or an ordered
choice.
Parameters: source - The source sequence. Parameters: target - The target element. The combined element. |
lookup | public Production lookup(NonTerminal nt)(Code) | | Look up the production for the specified nonterminal.
Parameters: nt - The nonterminal. The corresponding production or null if there is no such production. |
mark | public void mark(NonTerminal nt)(Code) | | Mark the specified nonterminal.
Parameters: nt - The nonterminal. |
marked | public Set marked()(Code) | | Get the set of marked nonterminals. Note that the called must
copy the set if it keeps the reference to the returned set after
the next use of this analyzer.
The marked set. |
matchesEmpty | public boolean matchesEmpty(Element e)(Code) | | Determine whether the specified element matches the empty input.
Note that this method assumes that nonterminals do not match the
empty input.
Parameters: e - The element. true if the specified element matches theempty input. |
matchingText | public String matchingText(Element e)(Code) | | Get the text matched by the specified element. This method
analyzes the specified element, and, if the element always
matches the same text, this method returns the constant text.
Otherwise, this method returns null . Note that this
method ignores predicates, actions, and value elements, as they
do not change the text matched by an element. Further note that
this method recursively analyzes referenced nonterminals.
Parameters: e - The element. The constant text. |
normalize | public Sequence normalize(Sequence s)(Code) | | Normalize the specified sequence for
Analyzer.join(Sequence,Element) joining with other elements during
terminal optimization. Currently, this method converts string
literals into equivalent subsequences of character literals.
Parameters: s - The sequence. The optimized sequence. |
notWorkingOn | public void notWorkingOn(NonTerminal nt)(Code) | | Set the status of the specified nonterminal as not being worked
on.
Parameters: nt - The nonterminal. |
option | public NonTerminal option()(Code) | | Create a new nonterminal for an option.
The new nonterminal. |
plus | public NonTerminal plus()(Code) | | Create a new nonterminal for one or more repetitions.
The new nonterminal. |
process | public void process(Production p)(Code) | | Process the specified production. This method clears the set of
working nonterminals. It also resets the counters for creating
new variables and nonterminals (besides the counter for shared
productions). It then invokes this analyzer's visitor on the
specified production. This method should be called within the
loop iterating over a grammar's productions, but not at other
locations within a visitor.
Parameters: p - The production. |
processed | public void processed(NonTerminal nt)(Code) | | Set the status of the specified nonterminal as processed.
Parameters: nt - The nonterminal. |
remove | public void remove(Production p)(Code) | | Prepare the specified production for removal from the grammar.
This method removes the specified production from the mapping
from nonterminals to productions and, if present, from the set of
top-level nonterminals. However, removal is not complete: the
production still needs to be removed from the grammar itself.
This is typically done within the main loop iterating over a
grammar's productions.
Parameters: p - The production. |
reset | public void reset()(Code) | | Forcibly reset the analyzer utility.
|
shared | public NonTerminal shared()(Code) | | Create a new nonterminal for a shared production.
The new nonterminal. |
star | public NonTerminal star()(Code) | | Create a new nonterminal for zero or more repetitions.
The new nonterminal. |
strip | public Element strip(Element e)(Code) | | Strip unnecessary ordered choices and sequences from the specified
element. A choice or sequence is unnecessary if it contains only
a single element.
Parameters: e - The element. The stripped element. |
unmark | public void unmark(NonTerminal nt)(Code) | | Unmark the specified nonterminal.
Parameters: nt - The nonterminal. |
variable | public String variable()(Code) | | Create a new temporary variable.
The name of the temporary variable. |
working | public Set working()(Code) | | Get the set of nonterminals being worked on. Note that the
caller must copy the set if it keeps the reference to the
returned set after the next call to
Analyzer.process .
The working set. |
workingOn | public void workingOn(NonTerminal nt)(Code) | | Set the status of the specified nonterminal as being worked on.
Parameters: nt - The nonterminal. |
|
|
|