// 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.