unit dpglib.AlternativeBlock; interface uses System.Classes, dpgrtl.types, dpglib.types, dpglib.AlternativeElem; type TAlternativeBlock = class( TAlternativeElem, IAlternativeBlock, IGrammarElem) // --------------------------------------------------------------- // Members // --------------------------------------------------------------- protected fAlternatives : TInterfaceList; fInitAction : AnsiString; fLabel : AnsiString; fAltI : integer; fAltJ : integer; fAnalysisAlt : integer; fHasAnAction : boolean; fHasASynPred : boolean; fID : integer; fNot : boolean; fGreedy : boolean; // (true) fGreedySet : boolean; // (false) fDoAutoGen : boolean; // (true) fWarnFollowAmbig : boolean; // (true) fGenAmbigWarnings : boolean; // (true) // --------------------------------------------------------------- // Constructor/destructor // --------------------------------------------------------------- public constructor Create( Grammar : IGrammar); overload; constructor Create( Grammar : IGrammar; Start : IToken; Invert : boolean); overload; // --------------------------------------------------------------- // IGrammarElem overrides // --------------------------------------------------------------- public procedure Generate; function Look( K: integer) : ILookahead; function AsString : AnsiString; // --------------------------------------------------------------- // IAlternativeElem overrides // --------------------------------------------------------------- protected function GetLabel : AnsiString; procedure SetLabel( Lbl: AnsiString); // --------------------------------------------------------------- // IAlternativeBlock methods // --------------------------------------------------------------- protected function GetID : integer; function GetInitAction : AnsiString; function GetAutoGen : boolean; function GetNot : boolean; function GetHasASynPred : boolean; function GetHasAnAction : boolean; function GetWarnFollowAmbig : boolean; function GetGenAmbigWarnings : boolean; function GetGreedy : boolean; function GetGreedySet : boolean; function GetAlternatives : TInterfaceList; function GetAlternative( i: integer) : IAlternative; function GetAnalyzisAlt : integer; function GetAltI : integer; function GetAltJ : integer; procedure SetInitAction( Action : AnsiString); procedure SetAutoGen( AutoGen : boolean); procedure SetNot( Invert : boolean); procedure SetHasASynPred( SynPred : boolean); procedure SetHasAnAction( Action : boolean); procedure SetWarnFollowAmbig( Warn : boolean); procedure SetGenAmbigWarnings( Gen : boolean); procedure SetGreedy( Greedy : boolean); procedure SetGreedySet( GreedySet : boolean); procedure SetAlternatives( Alts : TInterfaceList); procedure SetAnalyzisAlt( Alt : integer); procedure SetAltI( AltI : integer); procedure SetAltJ( AltJ : integer); public procedure AddAlternative( Alt: IAlternative); procedure SetOption( Key, Value: IToken); procedure RemoveTracking( Grammar: IGrammar); procedure PrepareForAnalysis; virtual; end; implementation uses System.SysUtils, dpglib.Messages; var fNBlks : integer; // **************************************************************************** // Constructor/destructor // **************************************************************************** // ============================================================================ // Constructor // ============================================================================ constructor TAlternativeBlock.Create(Grammar: IGrammar); begin inherited Create( Grammar); fID := fNblks +1; fNot := false; fAlternatives := TInterfaceList.Create; fHasAnAction := false; fHasASynPred := false; fGreedy := true; fGreedySet := false; fDoAutoGen := true; fWarnFollowAmbig := true; fGenAmbigWarnings := true; inc( fNblks); end; // ============================================================================ // Constructor // ============================================================================ constructor TAlternativeBlock.Create( Grammar : IGrammar; Start : IToken; Invert : boolean); begin inherited Create( Grammar, Start); fID := fNblks +1; fNot := Invert; fAlternatives := TInterfaceList.Create; fHasAnAction := false; fHasASynPred := false; fGreedy := true; fGreedySet := false; fDoAutoGen := true; fWarnFollowAmbig := true; fGenAmbigWarnings := true; inc( fNblks); end; // **************************************************************************** // IGrammarElem overrides // **************************************************************************** // ============================================================================ // Generate // ============================================================================ procedure TAlternativeBlock.Generate; begin fGrammar.Generator.gen( self); end; // ============================================================================ // Look // ============================================================================ function TAlternativeBlock.Look(K: integer): ILookahead; begin result := fGrammar.LLkAnalyzer.Look( K, self); end; // ============================================================================ // AsString // ============================================================================ function TAlternativeBlock.AsString: AnsiString; begin result := ''; end; // **************************************************************************** // IAlternativeElem overrides // **************************************************************************** // ============================================================================ // GetLabel // ============================================================================ function TAlternativeBlock.GetLabel: AnsiString; begin result := fLabel; end; // ============================================================================ // SetLabel // ============================================================================ procedure TAlternativeBlock.SetLabel(Lbl: AnsiString); begin fLabel := Lbl; end; // **************************************************************************** // IAlternativeBlock implementation // **************************************************************************** // ============================================================================ // GetID // ============================================================================ function TAlternativeBlock.GetID: integer; begin result := fID; end; // ============================================================================ // GetInitAction // ============================================================================ function TAlternativeBlock.GetInitAction: AnsiString; begin result := fInitAction; end; // ============================================================================ // GetAutoGen // ============================================================================ function TAlternativeBlock.GetAutoGen: boolean; begin result := fDoAutoGen; end; // ============================================================================ // GetNot // ============================================================================ function TAlternativeBlock.GetNot: boolean; begin result := fNot; end; // ============================================================================ // GetHasASynPred // ============================================================================ function TAlternativeBlock.GetHasASynPred: boolean; begin result := fHasASynPred; end; // ============================================================================ // GetGenAmbigWarnings // ============================================================================ function TAlternativeBlock.GetGenAmbigWarnings: boolean; begin result := fGenAmbigWarnings; end; // ============================================================================ // GetGreedy // ============================================================================ function TAlternativeBlock.GetGreedy: boolean; begin result := fGreedy; end; // ============================================================================ // GetGreedySet // ============================================================================ function TAlternativeBlock.GetGreedySet: boolean; begin result := fGreedySet; end; // ============================================================================ // GetHasAnAction // ============================================================================ function TAlternativeBlock.GetHasAnAction: boolean; begin result := fHasAnAction; end; // ============================================================================ // GetWarnFollowAmbig // ============================================================================ function TAlternativeBlock.GetWarnFollowAmbig: boolean; begin result := fWarnFollowAmbig; end; // ============================================================================ // GetAlternatives // ============================================================================ function TAlternativeBlock.GetAlternatives: TInterfaceList; begin result := fAlternatives; end; // ============================================================================ // GetAltI // ============================================================================ function TAlternativeBlock.GetAltI: integer; begin result := fAltI; end; // ============================================================================ // GetAltJ // ============================================================================ function TAlternativeBlock.GetAltJ: integer; begin result := fAltJ; end; // ============================================================================ // GetAnalyzisAlt // ============================================================================ function TAlternativeBlock.GetAnalyzisAlt: integer; begin result := fAnalysisAlt; end; // ============================================================================ // GetAlternative // ============================================================================ function TAlternativeBlock.GetAlternative(i: integer): IAlternative; begin if (i>=0) and (i nil do begin // --------------------------------------------------------- // Handle RuleRef elements // --------------------------------------------------------- if elem.QueryInterface( IRuleRefElem, rr) = S_OK then begin Grammar.Symbol[rr.TargetRule].QueryInterface(IRuleSymbol,rs); if rs = nil then begin // pGrammar.Tool.Error( 'Rule "' + rr.TargetRule + '"' + // 'referenced in (...)=>, but not defined.', Grammar.Tool.Error( Format( MSG_E_INVRULEINSYNPRED, [rr.TargetRule]), fGrammar.GrammarFile, 0,0); end else begin rs.References.Remove( rr); end; end // --------------------------------------------------------- // Recurse into subrules // --------------------------------------------------------- else if elem.QueryInterface(IAlternativeBlock,ab) = S_OK then begin ab.RemoveTracking( Grammar); end; elem := elem.Next; end; end; end; initialization fNBlks := 0; end.