xtc.parser
Class Analyzer

java.lang.Object
  extended by xtc.tree.Utility
      extended by xtc.parser.Analyzer

public class Analyzer
extends Utility

Utility for analyzing and modifying grammar modules. This class provides functionality that helps process either a collection of modules or a single module. In particular, it provides:

  • A mapping from module names to modules, which is initialized through init(Grammar) and accessed through lookup(String) and lookup(ModuleName). After initialization, the grammar can be accessed through grammar().

  • A mapping from nonterminals to productions, which is initialized either through init(Grammar) or init(Module) and accessed through lookup(NonTerminal), lookup(NonTerminal,Module), and lookupGlobally(NonTerminal). When initializing this mapping through a grammar, relative look ups can only be performed within the context of processing a module. Note that the mapping contains both qualified and unqualified names.

  • Methods to test for and access the top-level (or root) module of a grammar.

  • Methods to add and remove modules. These methods update both the mapping from module names to modules and from nonterminals to productions, but they do not update the current grammar.

  • Methods to test whether a module is imported by another, to trace a module's dependencies, and to test whether a module or any of its dependencies has a specified attribute.

  • Methods to test whether a production is defined by a module and to test whether a production is imported by a module.

  • Methods to start processing a module and to determine the current module; additionally, methods to switch to a different module and switch back again when processing productions from several modules.

  • A method to uniquely uniquify() the names of all productions across all modules.

  • Methods to start processing a production and to 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 recursions, the marked set tracks the productions having the property, and the processed set (which typically is a superset of the marked set) tracks the analyzed productions. The working set is accessed through workingOn(NonTerminal), notWorkingOn(NonTerminal), notWorkingOnAny(), isBeingWorkedOn(NonTerminal), and working(). The marked set is accessed through mark(NonTerminal), mark(Collection), markAll(), unmark(NonTerminal), unmarkAll(), hasMarked(), isMarked(NonTerminal), and marked(). Finally, the processed set is accessed through clearProcessed(), processed(NonTerminal), and isProcessed(NonTerminal). Note that all nonterminals used in these sets should be fully qualified.

  • Methods to add and remove productions from a grammar. New productions are prepared for addition through add(FullProduction) and committed to the grammar through addNewProductionsAt(int). Existing productions are removed through remove(FullProduction).

  • A set of methods for creating synthetic variable names and nonterminals for new productions: variable(), split(), choice(), star(), plus(), option(), tail(), and shared(). Also, a method to test whether a given variable or nonterminal is synthetic. Besides shared variables, synthetic variables can only be created while processing a production.

  • A method to strip unnecessary ordered choices and sequences from an element and a method to strip only ordered choices.

  • A method to copy an element.

  • A set of methods for optimizing sequences that start with terminals through character switches: hasTerminalPrefix(Sequence), normalizeTerminals(Sequence), and joinTerminals(Sequence,Element).

  • The corresponding set of methods for folding common prefixes: haveCommonPrefix(Sequence,Sequence), normalizePrefix(Sequence,Sequence), and joinPrefixes(Sequence,Element).

  • A method to get the text of an element.

  • A method to determine whether an element restricts the input.

  • A method to determine whether an element consumes the input.

  • A method to determine whether an element matches the empty input.

  • A method to determine whether an element relies only on not-followed-by predicates.

  • A set of methods to process bindings, notably a method to determine whether an element can be bound, a method to add a binding to a list of elements, a method to access the only binding in a list of elements, and methods to unbind and strip and unbind an element.

  • A method to get a list's value.
  • Two methods to determine whether an element or a list sets the semantic value, either through a binding, semantic action, or value element. Another method to determine whether a list sets the semantic value to null.

  • A method to determine whether an element's list value may be null.

  • A method to type an element.

  • To utilize this analyzer, the utility must be initialized with a grammar or a module and the visitor must be registered. When processing modules in a grammar, this utility must be notified. When processing productions, this utility must also be notified.

    The analyzer utility tracks the current grammar or module so that it need not recreate its internal state as long as the same analyzer utility is used across different visitors.

    Version:
    $Revision: 1.147 $
    Author:
    Robert Grimm

    Field Summary
    static java.lang.String CHOICE
              The suffix for nonterminals representing choices.
    protected  int choiceCount
              The count of lifted choices for the current production.
    static java.lang.String DUMMY
              The name for dummy variables (in case of errors).
    protected  Grammar grammar
              The grammar.
    protected  java.util.Map<NonTerminal,java.lang.Object> grammarPMap
              The grammar-wide map from nonterminals to productions.
    protected  boolean isGrammarMode
              Flag for whether we are processing a grammar or a module.
    static int MAX_COUNT
              The maximum character count for turning character classes into character switches.
    protected  Module mCurrent
              The current grammar module.
    protected  Module module
              The self-contained grammar module.
    protected  java.util.Map<java.lang.String,Module> moduleMap
              The map from module names (as strings) to module objects.
    static java.lang.String OPTION
              The suffix for nonterminals representing options.
    protected  int optionCount
              The count of desugared options for the current production.
    protected  Production pCurrent
              The current production.
    static java.lang.String PLUS
              The suffix for nonterminals representing one or more repetitions.
    protected  int plusCount
              The count of desugared plus repetitions for the current production.
    protected  java.util.Map<NonTerminal,FullProduction> pMap
              The map from nonterminals to productions for the current module.
    protected  java.util.Set<NonTerminal> pMarked
              The set of nonterminals corresponding to productions having been marked.
    protected  java.util.List<Production> pNew
              The list of newly added productions.
    protected  java.util.Set<NonTerminal> pProcessed
              The set of nonterminals corresponding to productions having been processed.
    protected  java.util.Set<NonTerminal> pWorking
              The set of nonterminals corresponding to productions currently being processed.
    static java.lang.String SEPARATOR
              The separator character for creating new nonterminals, which should be illegal in regular variable or nonterminal names.
    static java.lang.String SHARED
              The base name for nonterminals representing shared productions.
    protected  int sharedCount
              The count of shared productions.
    static java.lang.String SPLIT
              The suffix for nonterminals representing split alternatives.
    protected  int splitCount
              The count of splits for the current production.
    static java.lang.String STAR
              The suffix for nonterminals representing zero or more repetitions.
    protected  int starCount
              The count of desugared star repetitions for the current production.
    static java.lang.String TAIL
              The suffix for nonterminals representing tail productions.
    protected  int tailCount
              The count of tail productions for the current production.
    protected  int varCount
              The count of synthetic variables for the current production.
    static java.lang.String VARIABLE
              The base name for synthetic variables.
    protected  Copier xerox
              The element copier.
     
    Constructor Summary
    Analyzer()
              Create a new analyzer utility.
     
    Method Summary
     void add(FullProduction p)
              Prepare the specified production for addition to the grammar module.
     void add(Module m)
              Add the specified module to the current grammar.
     int addNewProductionsAt(int idx)
              Add the newly generated productions to the grammar itself.
     Binding bind(java.util.List<Element> l)
              Bind the elements in the specified list.
     Binding bind(java.util.List<Element> l, java.lang.String marker)
              Bind the elements in the specified list.
     NonTerminal choice()
              Create a new nonterminal for a choice.
     void clearProcessed()
              Clear the processed status of all nonterminals.
     boolean consumesInput(Element e)
              Determine whether the specified element may consume the input.
     Module copy(Module m)
              Make a deep copy of the specified module.
    <T extends Element>
    T
    copy(T e)
              Make a deep copy of the specified element.
     Production current()
              Get the production currently being processed.
     Module currentModule()
              Get the module currently being processed.
     java.lang.Object enter(Production p)
              Enter the specified production.
     void exit(java.lang.Object closure)
              Exit a previously entered production.
    static Binding getBinding(java.util.List<Element> l)
              Get the binding for the specified list's value.
     Element getValue(java.util.List<Element> list, boolean ignoreActions)
              Get the specified list's semantic value.
     int getVarCount()
              Get the current counter for synthetic variables.
     Grammar grammar()
              Get the initializing grammar.
     boolean hasAttribute(Module m, java.lang.String name, java.util.Set<ModuleName> visited)
              Determine whether the specified module or any of its import or modification dependencies has an attribute with the specified name.
     boolean hasMarked()
              Determine whether any nonterminals are marked.
     boolean hasTerminalPrefix(Sequence s)
              Determine whether the specified sequence starts with terminals that can be optimized.
     boolean haveCommonPrefix(Sequence s1, Sequence s2)
              Determine whether the specified sequences start with prefixes that can be folded.
     void init(Grammar g)
              Initialize this analyzer for the specified grammar.
     void init(Module m)
              Initialize this analyzer for the specified module.
     boolean isBeingWorkedOn(NonTerminal nt)
              Determine whether the specified nonterminal is being worked on.
     boolean isBindable(Element e)
              Determine whether the specified element can be bound.
     boolean isDefined(Production p, Module m)
              Determine whether the specified production is defined by the specified module.
     boolean isImported(Production p, Module m)
              Determine whether the specified production is defined by a module imported by the specified module.
     boolean isImported(java.lang.String name, Module m)
              Determine whether the module with the specified name is imported by the specified module.
     boolean isMarked(NonTerminal nt)
              Determine whether the specified nonterminal has been marked.
     boolean isNotFollowedBy(Element e)
              Determine whether the specified element is a not-followed-by predicate.
     boolean isProcessed(NonTerminal nt)
              Determine whether the specified nonterminal has been processed.
    static boolean isSynthetic(NonTerminal nt)
              Determine whether the specified nonterminal is synthetic.
    static boolean isSynthetic(java.lang.String var)
              Determine whether the specified variable is a synthetic variable.
     boolean isTopLevel(Module m)
              Determine whether the specified module is the top-level module.
     Element joinPrefixes(Sequence source, Element target)
              Join the specified sequence with the specified element.
     Element joinTerminals(Sequence source, Element target)
              Join the specified sequence with the specified element.
     Module lookup(ModuleName module)
              Look up the specified module.
     FullProduction lookup(NonTerminal nt)
              Look up the production for the specified nonterminal.
     FullProduction lookup(NonTerminal nt, Module m)
              Look up the production for the specified nonterminal, which is also defined by the specified module.
     Module lookup(java.lang.String module)
              Look up the specified module.
     FullProduction lookupGlobally(NonTerminal nt)
              Look up the production for the specified qualified nonterminal.
     void mark(java.util.Collection<NonTerminal> nts)
              Mark the specified nonterminals.
     void mark(NonTerminal nt)
              Mark the specified nonterminal.
     void markAll()
              Mark all of a grammar module's nonterminals.
     java.util.Set<NonTerminal> marked()
              Get the set of marked nonterminals.
     boolean matchesEmpty(Element e)
              Determine whether the specified element matches the empty input.
     java.lang.String matchingText(Element e)
              Get the text matched by the specified element.
     boolean mayBeNull(Element element)
              Determine whether the list value of the specified element may be null.
     Module module()
              Get the initializing module.
     Sequence normalizePrefix(Sequence s1, Sequence s2)
              Normalize the specified sequences for joining with other sequences during prefix folding.
     Sequence normalizeTerminals(Sequence s)
              Normalize the specified sequence for joining with other elements during terminal optimization.
     void notWorkingOn(NonTerminal nt)
              Set the status of the specified nonterminal as not being worked on.
     void notWorkingOnAny()
              Set the status of all nonterminals as not being worked on.
     NonTerminal option()
              Create a new nonterminal for an option.
     NonTerminal plus()
              Create a new nonterminal for one or more repetitions.
     void process(Module m)
              Process the specified module.
     void process(Production p)
              Process the specified production.
     void processed(NonTerminal nt)
              Set the status of the specified nonterminal as processed.
     void remove(FullProduction p)
              Prepare the specified production for removal from the grammar.
     void remove(Module m)
              Remove the specified module from the current grammar.
     void reset()
              Forcibly reset the analyzer utility.
     void resetVarCount()
              Reset the counter for synthetic variables.
     boolean restrictsInput(Element e)
              Determine whether the specified element restricts the input.
    static boolean setsNullValue(java.util.List<Element> l)
              Determine whether the specified list of elements sets the semantic value to null.
    static boolean setsValue(Element e, boolean all)
              Determine whether the specified element sets the semantic value.
    static boolean setsValue(java.util.List<Element> l, boolean all)
              Determine whether the specified list of elements sets the semantic value.
     void setVarCount(int count)
              Set the counter for synthetic variables.
     NonTerminal shared()
              Create a new nonterminal for a shared production.
     NonTerminal split()
              Create a new nonterminal for a split.
     NonTerminal star()
              Create a new nonterminal for zero or more repetitions.
     void startAdding()
              Clear the list of newly generated productions.
    static Element strip(Element e)
              Strip unnecessary ordered choices and sequences from the specified element.
    static Element stripAndUnbind(Element e)
              Strip and unbind the specified element.
    static OrderedChoice stripChoices(OrderedChoice c)
              Strip unnecessary ordered choices from the specified choice.
     NonTerminal tail()
              Create a new nonterminal for a tail production.
     Module topLevel()
              Get the top-level module.
     void trace(Module m, java.util.Set<ModuleName> imports, java.util.Map<ModuleName,java.lang.Boolean> modified)
              Trace the specified module's dependencies.
     Type type(Element element)
              Type the specified element.
    static Element unbind(Element e)
              Unbind the specified element.
     void uniquify()
              Rename all productions to have unique names.
     void unmark(NonTerminal nt)
              Unmark the specified nonterminal.
     void unmarkAll()
              Unmark all nonterminals.
     java.lang.String variable()
              Create a new synthetic variable.
     java.lang.String variable(java.lang.String marker)
              Create a new synthetic variable with the specified marker.
     java.util.Set<NonTerminal> working()
              Get the set of nonterminals being worked on.
     void workingOn(NonTerminal nt)
              Set the status of the specified nonterminal as being worked on.
     
    Methods inherited from class xtc.tree.Utility
    register, visitor
     
    Methods inherited from class java.lang.Object
    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
     

    Field Detail

    SEPARATOR

    public static final java.lang.String SEPARATOR
    The separator character for creating new nonterminals, which should be illegal in regular variable or nonterminal names.

    See Also:
    Constant Field Values

    SHARED

    public static final java.lang.String SHARED
    The base name for nonterminals representing shared productions.

    See Also:
    Constant Field Values

    VARIABLE

    public static final java.lang.String VARIABLE
    The base name for synthetic variables.

    See Also:
    Constant Field Values

    DUMMY

    public static final java.lang.String DUMMY
    The name for dummy variables (in case of errors).

    See Also:
    Constant Field Values

    SPLIT

    public static final java.lang.String SPLIT
    The suffix for nonterminals representing split alternatives.

    See Also:
    Constant Field Values

    CHOICE

    public static final java.lang.String CHOICE
    The suffix for nonterminals representing choices.

    See Also:
    Constant Field Values

    STAR

    public static final java.lang.String STAR
    The suffix for nonterminals representing zero or more repetitions.

    See Also:
    Constant Field Values

    PLUS

    public static final java.lang.String PLUS
    The suffix for nonterminals representing one or more repetitions.

    See Also:
    Constant Field Values

    OPTION

    public static final java.lang.String OPTION
    The suffix for nonterminals representing options.

    See Also:
    Constant Field Values

    TAIL

    public static final java.lang.String TAIL
    The suffix for nonterminals representing tail productions.

    See Also:
    Constant Field Values

    MAX_COUNT

    public static final int MAX_COUNT
    The maximum character count for turning character classes into character switches.

    See Also:
    Constant Field Values

    xerox

    protected final Copier xerox
    The element copier.


    isGrammarMode

    protected boolean isGrammarMode
    Flag for whether we are processing a grammar or a module.


    grammar

    protected Grammar grammar
    The grammar.


    moduleMap

    protected java.util.Map<java.lang.String,Module> moduleMap
    The map from module names (as strings) to module objects.


    grammarPMap

    protected java.util.Map<NonTerminal,java.lang.Object> grammarPMap
    The grammar-wide map from nonterminals to productions. For each production, this map contains two entries, one mapping the fully qualified name to the production, the other mappiing the unqualified name to either a production (if the set of modules only contains a single production with the unqualified name) or a list of productions (if the set of resolved modules contains more than one production with the unqualified name). Note that this map does not contain partial productions.


    mCurrent

    protected Module mCurrent
    The current grammar module.


    module

    protected Module module
    The self-contained grammar module.


    pMap

    protected java.util.Map<NonTerminal,FullProduction> pMap
    The map from nonterminals to productions for the current module.


    pCurrent

    protected Production pCurrent
    The current production.


    pWorking

    protected java.util.Set<NonTerminal> pWorking
    The set of nonterminals corresponding to productions currently being processed.


    pMarked

    protected java.util.Set<NonTerminal> pMarked
    The set of nonterminals corresponding to productions having been marked.


    pProcessed

    protected java.util.Set<NonTerminal> pProcessed
    The set of nonterminals corresponding to productions having been processed.


    pNew

    protected java.util.List<Production> pNew
    The list of newly added productions.


    varCount

    protected int varCount
    The count of synthetic variables for the current production.


    splitCount

    protected int splitCount
    The count of splits for the current production.


    choiceCount

    protected int choiceCount
    The count of lifted choices for the current production.


    starCount

    protected int starCount
    The count of desugared star repetitions for the current production.


    plusCount

    protected int plusCount
    The count of desugared plus repetitions for the current production.


    optionCount

    protected int optionCount
    The count of desugared options for the current production.


    tailCount

    protected int tailCount
    The count of tail productions for the current production.


    sharedCount

    protected int sharedCount
    The count of shared productions.

    Constructor Detail

    Analyzer

    public Analyzer()
    Create a new analyzer utility.

    Method Detail

    reset

    public void reset()
    Forcibly reset the analyzer utility.


    init

    public void init(Grammar g)
    Initialize this analyzer for the specified grammar. This method initializes the map from module names to modules and the grammar-wide map from nonterminals to productions. It also sets the qualified name field for each production (if it has not been initialized). This method also clears the sets of marked and processed nonterminals. It should be called before iterating over the grammar's modules.

    Parameters:
    g - The grammar.

    isImported

    public boolean isImported(java.lang.String name,
                              Module m)
    Determine whether the module with the specified name is imported by the specified module.

    Parameters:
    name - The module name.
    m - The depending module.
    Returns:
    true if the specified module (or any of the modules modified by that module) imports the module with the specified name.

    trace

    public void trace(Module m,
                      java.util.Set<ModuleName> imports,
                      java.util.Map<ModuleName,java.lang.Boolean> modified)
    Trace the specified module's dependencies. This method traces the transitive closure of the specified module's import and modification dependencies. It adds the names of all imported modules to the imports set (excluding the name of the specified module) and the names of all modified modules to the modified map. The corresponding value in this mapping is Boolean.TRUE if the module is modified more than once. Otherwise, it is false. This method assumes that each module modification's modification field has been correctly initialized. Furthermore, the specified set and map should be empty, with the exception of the set of imported modules containing the name of the root module.

    Parameters:
    m - The module.
    imports - The imported modules.
    modified - The modified modules.

    hasAttribute

    public boolean hasAttribute(Module m,
                                java.lang.String name,
                                java.util.Set<ModuleName> visited)
    Determine whether the specified module or any of its import or modification dependencies has an attribute with the specified name.

    Parameters:
    m - The module.
    name - The attribute name.
    visited - An empty helper set.
    Returns:
    true if the specified module or any of its dependencies has the specified attribute.

    add

    public void add(Module m)
    Add the specified module to the current grammar. This method adds the specified module to the map from module names to modules and its productions to the grammar-wide map from nonterminals to productions. However, it does not add the specified module to the grammar's list of modules.

    Parameters:
    m - The module.
    Throws:
    java.lang.IllegalStateException - Signals that this analyzer has not been initialized with a grammar.

    remove

    public void remove(Module m)
    Remove the specified module from the current grammar. This method removes the specified module from the map from module names to modules and its productions from the grammar-wide map from nonterminals to productions. Note that this method does not remove the specified module from the grammar's list of modules.

    Parameters:
    m - The module.
    Throws:
    java.lang.IllegalStateException - Signals that this analyzer has not been initialized with a grammar.

    grammar

    public Grammar grammar()
    Get the initializing grammar.

    Returns:
    The grammar.
    Throws:
    java.lang.IllegalStateException - Signals that this analyzer has not been initialized with a grammar.
    See Also:
    init(Grammar)

    isTopLevel

    public boolean isTopLevel(Module m)
    Determine whether the specified module is the top-level module.

    Parameters:
    m - The module.
    Returns:
    true if the specified module is the top-level module.

    topLevel

    public Module topLevel()
    Get the top-level module.

    Returns:
    The top-level module.

    init

    public void init(Module m)
    Initialize this analyzer for the specified module. This method initializes the map from nonterminals to productions. It also clears the sets of marked and processed nonterminals. It should be called before iterating over the module's productions.

    Parameters:
    m - The self-contained module.

    module

    public Module module()
    Get the initializing module.

    Returns:
    The module.
    Throws:
    java.lang.IllegalStateException - Signals that this analyzer has not been initialized with a module.
    See Also:
    init(Module)

    lookup

    public Module lookup(java.lang.String module)
    Look up the specified module.

    Parameters:
    module - The module name.
    Returns:
    The corresponding module or null if there is no such module.
    Throws:
    java.lang.IllegalStateException - Signals that this analyzer has not been initialized with a grammar.

    lookup

    public Module lookup(ModuleName module)
    Look up the specified module.

    Parameters:
    module - The module name.
    Returns:
    The corresponding module or null if there is no such module.
    Throws:
    java.lang.IllegalStateException - Signals that this analyzer has not been initialized with a grammar.

    lookupGlobally

    public FullProduction lookupGlobally(NonTerminal nt)
    Look up the production for the specified qualified nonterminal.

    Parameters:
    nt - The nonterminal.
    Returns:
    The corresponding production or null if there is no such production.

    lookup

    public FullProduction lookup(NonTerminal nt,
                                 Module m)
    Look up the production for the specified nonterminal, which is also defined by the specified module.

    Parameters:
    nt - The nonterminal
    m - The module.
    Returns:
    The corresponding production or null if the specified module does not define a production with the specified nonterminal.
    Throws:
    java.lang.IllegalArgumentException - Signals multiple definitions for the specified nonterminal.
    java.lang.IllegalStateException - Signals that this analyzer has not been initialized with a grammar.

    lookup

    public FullProduction lookup(NonTerminal nt)
    Look up the production for the specified nonterminal. Note that, when processing a grammar, this method requires initializing calls to process(Module) to correctly resolve nonterminals.

    Parameters:
    nt - The nonterminal.
    Returns:
    The corresponding production or null if there is no such production.
    Throws:
    java.lang.IllegalArgumentException - Signals that there are multiple, ambiguous productions.

    isDefined

    public boolean isDefined(Production p,
                             Module m)
    Determine whether the specified production is defined by the specified module. This method works correctly in the presence of not yet applied module modifications, but it requires that this analyzer has been initialized with the corresponding grammar.

    Parameters:
    p - The production.
    m - The module.
    Returns:
    true if the production is defined by the specified module.

    isImported

    public boolean isImported(Production p,
                              Module m)
    Determine whether the specified production is defined by a module imported by the specified module. This method works correctly in the presence of not yet applied module modifications, but it requires that this analyzer has been initialized with the corresponding grammar.

    Parameters:
    p - The production.
    m - The module.
    Returns:
    true if the specified production is imported by the specified module.

    uniquify

    public void uniquify()
    Rename all productions to have unique names. Note that this method only works, if the corresponding visitor has initialized the analyzer with a grammar. Further note that this method may change a production's name as well as the internal mapping from nonterminals to productions. This method assumes that all partial productions have been applied.


    process

    public void process(Module m)
    Process the specified module. This method sets the current module when processing an entire grammar.

    Parameters:
    m - The module.

    currentModule

    public Module currentModule()
    Get the module currently being processed.

    Returns:
    The current module.

    enter

    public java.lang.Object enter(Production p)
    Enter the specified production. This method temporarily switches the current module to the production's module.

    Parameters:
    p - The production.
    Returns:
    A closure for exit(Object).

    exit

    public void exit(java.lang.Object closure)
    Exit a previously entered production. This method restores the current module to the state before the call to enter(Production).

    Parameters:
    closure - The closure returned from enter().

    process

    public void process(Production p)
    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 module's productions, but not at other locations within a visitor.

    Parameters:
    p - The production.

    current

    public Production current()
    Get the production currently being processed.

    Returns:
    The current production.

    workingOn

    public void workingOn(NonTerminal nt)
    Set the status of the specified nonterminal as being worked on.

    Parameters:
    nt - The nonterminal.

    notWorkingOn

    public void notWorkingOn(NonTerminal nt)
    Set the status of the specified nonterminal as not being worked on.

    Parameters:
    nt - The nonterminal.

    notWorkingOnAny

    public void notWorkingOnAny()
    Set the status of all nonterminals as not being worked on.


    isBeingWorkedOn

    public boolean isBeingWorkedOn(NonTerminal nt)
    Determine whether the specified nonterminal is being worked on.

    Parameters:
    nt - The nonterminal.
    Returns:
    true if the nonterminal is being worked on.

    working

    public java.util.Set<NonTerminal> working()
    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 process(xtc.parser.Module).

    Returns:
    The working set.

    mark

    public void mark(NonTerminal nt)
    Mark the specified nonterminal.

    Parameters:
    nt - The nonterminal.

    mark

    public void mark(java.util.Collection<NonTerminal> nts)
    Mark the specified nonterminals.

    Parameters:
    nts - The list of nonterminals.

    markAll

    public void markAll()
    Mark all of a grammar module's nonterminals.


    unmark

    public void unmark(NonTerminal nt)
    Unmark the specified nonterminal.

    Parameters:
    nt - The nonterminal.

    unmarkAll

    public void unmarkAll()
    Unmark all nonterminals.


    hasMarked

    public boolean hasMarked()
    Determine whether any nonterminals are marked.

    Returns:
    true if any nonterminal has been marked.

    isMarked

    public boolean isMarked(NonTerminal nt)
    Determine whether the specified nonterminal has been marked.

    Parameters:
    nt - The nonterminal.
    Returns:
    true if the nonterminal has been marked.

    marked

    public java.util.Set<NonTerminal> marked()
    Get the set of marked nonterminals. Note that the caller must copy the set if it keeps the reference to the returned set after the next use of this analyzer.

    Returns:
    The marked set.

    clearProcessed

    public void clearProcessed()
    Clear the processed status of all nonterminals.


    processed

    public void processed(NonTerminal nt)
    Set the status of the specified nonterminal as processed.

    Parameters:
    nt - The nonterminal.

    isProcessed

    public boolean isProcessed(NonTerminal nt)
    Determine whether the specified nonterminal has been processed.

    Parameters:
    nt - The nonterminal.
    Returns:
    true if the nonterminal has been processed.

    startAdding

    public void startAdding()
    Clear the list of newly generated productions. This method needs to be called before a processing step that may add new productions through add(FullProduction) and addNewProductionsAt(int).


    add

    public void add(FullProduction p)
    Prepare the specified production for addition to the grammar module. 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 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 method.

    Parameters:
    p - The new production.

    addNewProductionsAt

    public int addNewProductionsAt(int idx)
    Add the newly generated productions to the grammar itself. This method adds the productions collected through 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.
    Returns:
    The number of productions added.

    remove

    public void remove(FullProduction 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. 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.

    resetVarCount

    public void resetVarCount()
    Reset the counter for synthetic variables. Note that process(Production) already resets this counter; this method provides more fine-grained control.


    getVarCount

    public int getVarCount()
    Get the current counter for synthetic variables.

    Returns:
    The current counter.

    setVarCount

    public void setVarCount(int count)
    Set the counter for synthetic variables.

    Parameters:
    count - The new counter value.

    variable

    public java.lang.String variable()
    Create a new synthetic variable.

    Returns:
    The name of the synthetic variable.

    variable

    public java.lang.String variable(java.lang.String marker)
    Create a new synthetic variable with the specified marker.

    Parameters:
    marker - The marker.
    Returns:
    The name of the synthetic variable.

    isSynthetic

    public static boolean isSynthetic(java.lang.String var)
    Determine whether the specified variable is a synthetic variable.

    Parameters:
    var - The variable name.
    Returns:
    true if the specified variable name is a synthetic variable returned by variable().

    split

    public NonTerminal split()
    Create a new nonterminal for a split.

    Returns:
    The new nonterminal.

    choice

    public NonTerminal choice()
    Create a new nonterminal for a choice.

    Returns:
    The new nonterminal.

    star

    public NonTerminal star()
    Create a new nonterminal for zero or more repetitions.

    Returns:
    The new nonterminal.

    plus

    public NonTerminal plus()
    Create a new nonterminal for one or more repetitions.

    Returns:
    The new nonterminal.

    option

    public NonTerminal option()
    Create a new nonterminal for an option.

    Returns:
    The new nonterminal.

    tail

    public NonTerminal tail()
    Create a new nonterminal for a tail production.

    Returns:
    The new nonterminal.

    shared

    public NonTerminal shared()
    Create a new nonterminal for a shared production.

    Returns:
    The new nonterminal.

    isSynthetic

    public static boolean isSynthetic(NonTerminal nt)
    Determine whether the specified nonterminal is synthetic.

    Parameters:
    nt - The nonterminal.
    Returns:
    true if the nonterminal is synthetic.

    strip

    public static Element strip(Element e)
    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.
    Returns:
    The stripped element.

    stripChoices

    public static OrderedChoice stripChoices(OrderedChoice c)
    Strip unnecessary ordered choices from the specified choice. A choice is unnecessary if it contains only a single choice.

    Parameters:
    c - The choice.
    Returns:
    The stripped choice.

    copy

    public Module copy(Module m)
    Make a deep copy of the specified module.

    Parameters:
    m - The module.
    Returns:
    A deep copy.

    copy

    public <T extends Element> T copy(T e)
    Make a deep copy of the specified element.

    Parameters:
    e - The element.
    Returns:
    A deep copy.

    hasTerminalPrefix

    public boolean hasTerminalPrefix(Sequence s)
    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.
    Returns:
    true if the sequence starts with optimizable terminals.

    normalizeTerminals

    public Sequence normalizeTerminals(Sequence s)
    Normalize the specified sequence for joining with other elements during terminal optimization. Currently, this method converts string literals into equivalent subsequences of character literals.

    Parameters:
    s - The sequence.
    Returns:
    The normalized sequence.

    joinTerminals

    public Element joinTerminals(Sequence source,
                                 Element target)
    Join the specified sequence with the specified element. Note that the specified sequence must have been normalized. Further note that the combined element is guaranteed to either be a sequence or an ordered choice.

    Parameters:
    source - The source sequence.
    target - The target element.
    Returns:
    The combined element.

    haveCommonPrefix

    public boolean haveCommonPrefix(Sequence s1,
                                    Sequence s2)
    Determine whether the specified sequences start with prefixes that can be folded.

    Parameters:
    s1 - The first sequence.
    s2 - The second sequence.
    Returns:
    true if the two sequences start with prefixes that can be folded.

    normalizePrefix

    public Sequence normalizePrefix(Sequence s1,
                                    Sequence s2)
    Normalize the specified sequences for joining with other sequences during prefix folding. The first specified sequence should always be the first sequence that has a common prefix with sequences following in an ordered choice, while the second specified sequence should iterate over the following sequences.

    Parameters:
    s1 - The first sequence.
    s2 - The second sequence.
    Returns:
    The normalized second sequence.

    joinPrefixes

    public Element joinPrefixes(Sequence source,
                                Element target)
    Join the specified sequence with the specified element. Note that the specified sequence must have been normalized. Further note that that the combined element is guaranteed to either be a sequence or an ordered choice.

    Parameters:
    source - The source sequence.
    target - The target element.
    Returns:
    The combined element.

    matchingText

    public java.lang.String matchingText(Element e)
    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 static text. Otherwise, this method returns null. Note that this method ignores predicates, actions, node markers, null literals, 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.
    Returns:
    The constant text.

    restrictsInput

    public boolean restrictsInput(Element e)
    Determine whether the specified element restricts the input. Note that this method requires that the production and module containing the element are currently being processed; i.e., the corresponding process() invocations must have been performed. Further note that this method internally uses this analyzer's working set. Finally, note that, after processing a production, this method sets the production's Properties.RESTRICT property.

    Parameters:
    e - The element.
    Returns:
    true if the element restricts the input.

    consumesInput

    public boolean consumesInput(Element e)
    Determine whether the specified element may consume the input. Note that this method requires that the production and module containing the element are currently being processed; i.e., the corresponding process() invocations must have been performed. Further note that this method internally uses this analyzer's working set. Finally, note that, after processing a production, this method sets the production's Properties.CONSUMER property.

    Parameters:
    e - The element.
    Returns:
    true if the element consumes the input.

    matchesEmpty

    public boolean matchesEmpty(Element e)
    Determine whether the specified element matches the empty input. Note that this method requires that the production and module containing the element are currently being processed; i.e., the corresponding process() invocations must have been performed. Further note that this method internally uses this analyzer's working set. Finally, note that, after processing a production, this method sets the production's Properties.EMPTY property.

    Parameters:
    e - The element.
    Returns:
    true if the element matches the empty input.

    isNotFollowedBy

    public boolean isNotFollowedBy(Element e)
    Determine whether the specified element is a not-followed-by predicate. Note that this method requires that the production and module containing the element are currently being processed; i.e., the corresponding process() invocations must have been performed.

    Parameters:
    e - The element.
    Returns:
    true if the specified element is a not-followed-by predicate.

    isBindable

    public boolean isBindable(Element e)
    Determine whether the specified element can be bound. This method returns true if the specified element is recognized by bind(List) and bind(List,String) as capturing a list's semantic value.

    Parameters:
    e - The element.
    Returns:
    true if the element can be bound.

    bind

    public Binding bind(java.util.List<Element> l)
    Bind the elements in the specified list. This method analyzes the specified list and, if possible, adds in a binding for the semantic value of the elements in the list. If the list does not have a unique binding to capture the semantic value, this method returns null to indicate the need for an explicitly specified semantic value.

    Parameters:
    l - The list to bind.
    Returns:
    The corresponding binding.

    bind

    public Binding bind(java.util.List<Element> l,
                        java.lang.String marker)
    Bind the elements in the specified list. This method analyzes the specified list and, if possible, adds in a binding for the semantic value of the elements in the list. If the list does not have a unique binding to capture the semantic value, this method returns null to indicate the need for an explicitly specified semantic value.

    Parameters:
    l - The list to bind.
    marker - The marker for the binding variable or null if no marker should be used.
    Returns:
    The corresponding binding.

    getBinding

    public static Binding getBinding(java.util.List<Element> l)
    Get the binding for the specified list's value. If the list has a single binding, this method returns it; otherwise (i.e., if the sequence has no binding or multiple bindings), this method returns null.

    Parameters:
    l - The list.
    Returns:
    The list's only binding (if it exists).

    unbind

    public static Element unbind(Element e)
    Unbind the specified element. If the element is a binding, this method returns the bound element. Otherwise, it returns the element.

    Parameters:
    e - The element.
    Returns:
    The unbound element.

    stripAndUnbind

    public static Element stripAndUnbind(Element e)
    Strip and unbind the specified element. Invoking this method on element e is semantically equivalent to:
     Analyzer.strip(Analyzer.unbind(Analyzer.strip(e)))
     

    Parameters:
    e - The element.
    Returns:
    The stripped and unbound element.

    getValue

    public Element getValue(java.util.List<Element> list,
                            boolean ignoreActions)
    Get the specified list's semantic value. If the specified list explicitly sets the list's semantic value through a binding, a semantic action, a parser action, or a value element, this method returns the last such element. Next, if the list has a single element with a semantic value, this method returns that element. Otherwise, this method returns null.

    Parameters:
    list - The list.
    ignoreActions - The flag for whether to ignore (parser) actions.
    Returns:
    The list's value or null if the value cannot be determined.

    setsValue

    public static boolean setsValue(java.util.List<Element> l,
                                    boolean all)
    Determine whether the specified list of elements sets the semantic value. This method determines whether any element either is a binding to yyValue, an action setting yyValue, or a value element.

    Parameters:
    l - The list.
    all - The flag for whether all alternatives of nested choices need to set the semantic value.
    Returns:
    true if the list sets the semantic value.

    setsValue

    public static boolean setsValue(Element e,
                                    boolean all)
    Determine whether the specified element sets the semantic value. This method determines whether the specified element contains either an explicit binding to yyValue, an action setting yyValue, or a value element.

    Parameters:
    e - The element.
    all - The flag for whether all alternatives of choices need to set the semantic value.
    Returns:
    true if the element sets the semantic value.

    setsNullValue

    public static boolean setsNullValue(java.util.List<Element> l)
    Determine whether the specified list of elements sets the semantic value to null. This method determines whether the only value-setting element is a null value. It ignores nested choices and sequences.

    Parameters:
    l - The list.
    Returns:
    true if the list sets the semantic value to null.

    mayBeNull

    public boolean mayBeNull(Element element)
    Determine whether the list value of the specified element may be null. This method returns true if the specified element is an option or a nonterminal representing a desguared option.

    Parameters:
    element - The element.
    Returns:
    true if the element's value may be null.

    type

    public Type type(Element element)
    Type the specified element. This method requires that this analyzer has been initialized with a grammar contained in a single module. It utilizes the type representation of AST and may return a Wildcard.

    Parameters:
    element - The element.
    Returns:
    The type.
    Throws:
    java.lang.IllegalArgumentException - Signals that the element cannot be typed.


    Copyright © 2012. All Rights Reserved.