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-terminalsP
- the type of productions, which must have the same types of (non-)terminals.
- All Implemented Interfaces:
java.lang.Iterable<P>
- Direct Known Subclasses:
AssemblyExtendedGrammar
,AssemblyGrammar
public abstract class AbstractAssemblyGrammar<NT extends AssemblyNonTerminal,P extends AbstractAssemblyProduction<NT>> extends java.lang.Object implements java.lang.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 (probablyAssemblyGrammar
) and calladdProduction(AbstractAssemblyProduction)
oraddProduction(AssemblyNonTerminal, AssemblySentential)
. The grammar object will collect the non-terminals and terminals. By default, the start symbol is taken from the left-hand side of the first production added to the grammar.
-
-
Field Summary
Fields Modifier and Type Field Description protected java.util.Map<java.lang.String,NT>
nonterminals
protected java.util.List<P>
prodList
protected org.apache.commons.collections4.MultiValuedMap<java.lang.String,P>
productions
protected java.lang.String
startName
protected java.util.Map<java.lang.String,AssemblySymbol>
symbols
protected java.util.Map<java.lang.String,AssemblyTerminal>
terminals
-
Constructor Summary
Constructors Constructor Description AbstractAssemblyGrammar()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description void
addProduction(NT lhs, AssemblySentential<NT> rhs)
Add a production to the grammarvoid
addProduction(P prod)
Add a production to the grammarvoid
combine(AbstractAssemblyGrammar<NT,P> that)
Add all the productions of a given grammar to this oneboolean
contains(java.lang.String name)
Check if the grammar contains any symbol with the given nameNT
getNonTerminal(java.lang.String name)
Get the named non-terminalNT
getStart()
Get the start symbol for the grammarjava.lang.String
getStartName()
Get the name of the start symbol for the grammarAssemblyTerminal
getTerminal(java.lang.String name)
Get the named terminalprotected boolean
isPureRecursive(P prod)
Check if the given production is purely recursive, i.e., of the form I => Ijava.util.Iterator<P>
iterator()
Traverse the productionsprotected 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.java.util.Collection<NT>
nonTerminals()
Get the non-terminalsvoid
print(java.io.PrintStream out)
Print the productions of this grammar to the given streamjava.util.Collection<P>
productionsOf(AssemblyNonTerminal nt)
Get all productions where the left-hand side is the given non-terminaljava.util.Collection<P>
productionsOf(java.lang.String name)
Get all productions where the left-hand side non-terminal has the given namevoid
setStart(AssemblyNonTerminal nt)
Change the start symbol for the grammarvoid
setStartName(java.lang.String startName)
Change the start symbol for the grammarjava.util.Collection<AssemblyTerminal>
terminals()
Get the terminalsvoid
verify()
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.
-
-
-
Field Detail
-
productions
protected final org.apache.commons.collections4.MultiValuedMap<java.lang.String,P extends AbstractAssemblyProduction<NT>> productions
-
prodList
protected final java.util.List<P extends AbstractAssemblyProduction<NT>> prodList
-
nonterminals
protected final java.util.Map<java.lang.String,NT extends AssemblyNonTerminal> nonterminals
-
terminals
protected final java.util.Map<java.lang.String,AssemblyTerminal> terminals
-
symbols
protected final java.util.Map<java.lang.String,AssemblySymbol> symbols
-
startName
protected java.lang.String startName
-
-
Method Detail
-
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 productionrhs
- 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 siderhs
- 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(java.lang.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 java.lang.String getStartName()
Get the name of the start symbol for the grammar- Returns:
- the name of the start symbol
-
getNonTerminal
public NT getNonTerminal(java.lang.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(java.lang.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(java.io.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 java.util.Iterator<P> iterator()
Traverse the productions- Specified by:
iterator
in interfacejava.lang.Iterable<NT extends AssemblyNonTerminal>
-
nonTerminals
public java.util.Collection<NT> nonTerminals()
Get the non-terminals- Returns:
-
terminals
public java.util.Collection<AssemblyTerminal> terminals()
Get the terminals- Returns:
-
productionsOf
public java.util.Collection<P> productionsOf(java.lang.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 java.util.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(java.lang.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
-
-