64 lines
1.8 KiB
ObjectPascal
64 lines
1.8 KiB
ObjectPascal
// The context needed to add root,child elements to a Tree. There is only one alternative
|
|
// (i.e., a list of children). We subclass to specialize. MakeGrammar.addElementToCurrentAlt
|
|
// will work correctly now for either a block of alts or a Tree child list.
|
|
//
|
|
// The first time addAlternativeElement is called, it sets the root element
|
|
// rather than adding it to one of the alternative lists. Rather than have
|
|
// the grammar duplicate the rules for grammar atoms etc... we use the same
|
|
// grammar and same refToken behavior etc... We have to special case somewhere
|
|
// and here is where we do it.
|
|
|
|
unit dpglib.TreeBlockContext;
|
|
|
|
interface
|
|
uses
|
|
dpglib.types,
|
|
dpglib.BlockContext;
|
|
|
|
type
|
|
TTreeBlockContext = class( TBlockContext)
|
|
protected
|
|
fNextElementIsRoot: boolean;
|
|
|
|
public
|
|
procedure AddAlternativeElem( pElem: IAlternativeElem); override;
|
|
|
|
public
|
|
procedure AfterConstruction; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TTreeBlockContext }
|
|
|
|
// ================================================================================================
|
|
// After Construction
|
|
// ================================================================================================
|
|
procedure TTreeBlockContext.AfterConstruction;
|
|
begin
|
|
inherited;
|
|
fNextElementIsRoot := true;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Add Alternative Elem
|
|
// ================================================================================================
|
|
procedure TTreeBlockContext.AddAlternativeElem(pElem: IAlternativeElem);
|
|
var
|
|
tree: ITreeElem;
|
|
|
|
begin
|
|
Block.QueryInterface( ITreeElem, tree);
|
|
|
|
if fNextElementIsRoot then
|
|
begin
|
|
tree.Root := pElem as IGrammarAtom;
|
|
fNextElementIsRoot := false
|
|
end
|
|
|
|
else
|
|
inherited
|
|
end;
|
|
|
|
end.
|