Class AbstractAssemblyGrammar<NT extends AssemblyNonTerminal,P extends AbstractAssemblyProduction<NT>>

java.lang.Object
ghidra.app.plugin.assembler.sleigh.grammars.AbstractAssemblyGrammar<NT,P>
Type Parameters:
NT - the type of non-terminals
P - the type of productions, which must have the same types of (non-)terminals.
All Implemented Interfaces:
Iterable<P>
Direct Known Subclasses:
AssemblyExtendedGrammar, AssemblyGrammar

public abstract class AbstractAssemblyGrammar<NT extends AssemblyNonTerminal,P extends AbstractAssemblyProduction<NT>> extends Object implements Iterable<P>
Defines a context-free grammar, usually for the purpose of parsing mnemonic assembly instructions

As in classic computer science, a CFG consists of productions of non-terminals and terminals. The left-hand side of the a production must be a single non-terminal, but the right-hand side may be any string of symbols. To avoid overloading the term "String," here we call it a "Sentential."

To define a grammar, simply construct an appropriate subclass (probably AssemblyGrammar) and call addProduction(AbstractAssemblyProduction) or addProduction(AssemblyNonTerminal, AssemblySentential).

By default, the start symbol is taken from the left-hand side of the first production added to the grammar.

  • Field Details

  • Constructor Details

    • AbstractAssemblyGrammar

      public AbstractAssemblyGrammar()
  • Method Details

    • newProduction

      protected abstract P newProduction(NT lhs, AssemblySentential<NT> rhs)
      Because a subclass may have a different type of production, it must provide a mechanism for constructing an appropriate production given just the LHS and RHS.
      Parameters:
      lhs - the left-hand side of the production
      rhs - the right-hand side of the production
      Returns:
      the constructed production
    • addProduction

      public void addProduction(NT lhs, AssemblySentential<NT> rhs)
      Add a production to the grammar
      Parameters:
      lhs - the left-hand side
      rhs - the right-hand side
    • addProduction

      public void addProduction(P prod)
      Add a production to the grammar
      Parameters:
      prod - the production
    • isPureRecursive

      protected boolean isPureRecursive(P prod)
      Check if the given production is purely recursive, i.e., of the form I => I
      Parameters:
      prod - the production to check
      Returns:
      true iff the production is purely recursive
    • setStart

      public void setStart(AssemblyNonTerminal nt)
      Change the start symbol for the grammar
      Parameters:
      nt - the new start symbol
    • setStartName

      public void setStartName(String startName)
      Change the start symbol for the grammar
      Parameters:
      startName - the name of the new start symbol
    • getStart

      public NT getStart()
      Get the start symbol for the grammar
      Returns:
      the start symbol
    • getStartName

      public String getStartName()
      Get the name of the start symbol for the grammar
      Returns:
      the name of the start symbol
    • getNonTerminal

      public NT getNonTerminal(String name)
      Get the named non-terminal
      Parameters:
      name - the name of the desired non-terminal
      Returns:
      the non-terminal, or null if it is not in this grammar
    • getTerminal

      public AssemblyTerminal getTerminal(String name)
      Get the named terminal
      Parameters:
      name - the name of the desired terminal
      Returns:
      the terminal, or null if it is not in this grammar
    • combine

      public void combine(AbstractAssemblyGrammar<NT,P> that)
      Add all the productions of a given grammar to this one
      Parameters:
      that - the grammar whose productions to add
    • print

      public void print(PrintStream out)
      Print the productions of this grammar to the given stream
      Parameters:
      out - the stream
    • verify

      public void verify() throws AssemblyGrammarException
      Check that the grammar is consistent

      The grammar is consistent if every non-terminal appearing in the grammar also appears as the left-hand side of some production. If not, such non-terminals are said to be undefined.

      Throws:
      AssemblyGrammarException - the grammar is inconsistent, i.e., contains undefined non-terminals.
    • iterator

      public Iterator<P> iterator()
      Traverse the productions
      Specified by:
      iterator in interface Iterable<NT extends AssemblyNonTerminal>
    • nonTerminals

      public Collection<NT> nonTerminals()
      Get the non-terminals
      Returns:
    • terminals

      public Collection<AssemblyTerminal> terminals()
      Get the terminals
      Returns:
    • productionsOf

      public Collection<P> productionsOf(String name)
      Get all productions where the left-hand side non-terminal has the given name
      Parameters:
      name - the name of the non-terminal
      Returns:
      all productions "defining" the named non-terminal
    • productionsOf

      public Collection<P> productionsOf(AssemblyNonTerminal nt)
      Get all productions where the left-hand side is the given non-terminal
      Parameters:
      nt - the non-terminal whose defining productions to find
      Returns:
      all productions "defining" the given non-terminal
    • contains

      public boolean contains(String name)
      Check if the grammar contains any symbol with the given name
      Parameters:
      name - the name to find
      Returns:
      true iff a terminal or non-terminal has the given name