Initial check in lib
This commit is contained in:
@@ -0,0 +1,621 @@
|
||||
unit dpglib.RuleBlock;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
dpgrtl.types,
|
||||
dpglib.Types,
|
||||
dpglib.Lookahead,
|
||||
dpglib.AlternativeBlock;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// TRuleBlock class specification
|
||||
// =========================================================================
|
||||
TRuleBlock = class( TAlternativeBlock,
|
||||
IRuleBlock,
|
||||
IAlternativeBlock,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fRuleName : AnsiString;
|
||||
fArguments : AnsiString;
|
||||
fThrowSpec : AnsiString;
|
||||
fReturnAction : AnsiString;
|
||||
fLocals : AnsiString;
|
||||
fIgnoreRule : AnsiString;
|
||||
|
||||
fExHandlerType : AnsiString;
|
||||
fExHandlerCode : AnsiString;
|
||||
|
||||
fEndNode : IRuleEndElem;
|
||||
|
||||
fLock : array of boolean;
|
||||
fCache : array of ILookahead;
|
||||
|
||||
fTestLiterals : boolean;
|
||||
fDefErrorHandler : boolean;
|
||||
|
||||
fLabeledElems : TInterfaceList;
|
||||
fOneOrMoreBlocks : TInterfaceList;
|
||||
fNMBlocks : TInterfaceList;
|
||||
fSynPredBlocks : TInterfaceList;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Internals
|
||||
// ---------------------------------------------------------------
|
||||
// protected
|
||||
// function FindExceptionSpec( pSpec: AnsiString) : IExceptionSpec; overload;
|
||||
// function FindExceptionSpec( pSpec: IToken): IExceptionSpec; overload;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pID : AnsiString); overload;
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pID : AnsiString;
|
||||
pLine : integer;
|
||||
pDoAutoGen : boolean); overload;
|
||||
|
||||
|
||||
destructor Destroy; override;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IAlternativeBlock overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure PrepareForAnalysis; override;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IRuleBlock methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetRuleName : AnsiString;
|
||||
function GetArguments : AnsiString;
|
||||
function GetThrowSpec : AnsiString;
|
||||
function GetReturnAction : AnsiString;
|
||||
function GetLocals : AnsiString;
|
||||
function GetEndNode : IRuleEndElem;
|
||||
|
||||
function GetTestLiterals : boolean;
|
||||
function GetLabeledElems : TInterfaceList;
|
||||
|
||||
function GetExHandlerType : AnsiString;
|
||||
function GetExHandlerCode : AnsiString;
|
||||
|
||||
function GetDefErrorHandler : boolean;
|
||||
function GetIgnoreRule : AnsiString;
|
||||
function GetOneOrMoreBlocks : TInterfaceList;
|
||||
function GetNMBlocks : TInterfaceList;
|
||||
function GetSynPredBlocks : TInterfaceList;
|
||||
|
||||
function GetLock( i: integer): boolean;
|
||||
function GetCache(i: integer): ILookahead;
|
||||
|
||||
procedure SetRuleName( pRuleName : AnsiString);
|
||||
procedure SetArguments( pArguments : AnsiString);
|
||||
procedure SetThrowSpec( pThrowSpec : AnsiString);
|
||||
procedure SetReturnAction( pAction : AnsiString);
|
||||
procedure SetLocals( pLocals : AnsiString);
|
||||
procedure SetEndNode( pNode : IRuleEndElem);
|
||||
|
||||
procedure SetTestLiterals( pTestLiterals : boolean);
|
||||
procedure SetLabeledElems( pLabeledElems : TInterfaceList);
|
||||
|
||||
procedure SetExHandlerType( pExType : AnsiString);
|
||||
procedure SetExHandlerCode( pExCode : AnsiString);
|
||||
|
||||
procedure SetDefErrorHandler( pErrorHandler : boolean);
|
||||
procedure SetIgnoreRule( pRule : AnsiString);
|
||||
|
||||
procedure SetLock( i:integer; pLock : boolean);
|
||||
procedure SetCache(i:integer; pCache : ILookahead);
|
||||
|
||||
public
|
||||
procedure AddExceptionSpec( pExceptionSpec : IExceptionSpec);
|
||||
procedure SetOption( pKey, pValue : IToken);
|
||||
function IsLexerAutoGenRule: boolean;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils,
|
||||
dpglib.Messages;
|
||||
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TRuleBlock.Create(pGrammar: IGrammar; pID: AnsiString);
|
||||
var
|
||||
pg: IParserGrammar;
|
||||
|
||||
begin
|
||||
inherited Create( pGrammar);
|
||||
|
||||
fRuleName := pID;
|
||||
fLabeledElems := TInterfaceList.Create;
|
||||
fOneOrMoreBlocks := TInterfaceList.Create;
|
||||
fNMBlocks := TInterfaceList.Create;
|
||||
fSynPredBlocks := TInterfaceList.Create;
|
||||
fLine := 0;
|
||||
|
||||
SetLength( fCache, fGrammar.MaxK +1);
|
||||
|
||||
if fGrammar.QueryInterface(IParserGrammar, pg) = S_OK then
|
||||
fDoAutoGen := true;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TRuleBlock.Create( pGrammar : IGrammar;
|
||||
pID : AnsiString;
|
||||
pLine : integer;
|
||||
pDoAutoGen : boolean);
|
||||
begin
|
||||
inherited Create( pGrammar);
|
||||
|
||||
fRuleName := pID;
|
||||
fLabeledElems := TInterfaceList.Create;
|
||||
fDoAutoGen := pDoAutoGen;
|
||||
fOneOrMoreBlocks := TInterfaceList.Create;
|
||||
fNMBlocks := TInterfaceList.Create;
|
||||
fSynPredBlocks := TInterfaceList.Create;
|
||||
fLine := pLine;
|
||||
|
||||
SetLength( fCache, fGrammar.MaxK +1);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TRuleBlock.Destroy;
|
||||
var
|
||||
i : integer;
|
||||
|
||||
begin
|
||||
FreeAndNil( fLabeledElems);
|
||||
FreeAndNil( fOneOrMoreBlocks);
|
||||
FreeAndNil( fNMBlocks);
|
||||
FreeAndNil( fSynPredBlocks);
|
||||
|
||||
for i:=Low(fCache) to High(fCache) do
|
||||
fCache[i] := nil;
|
||||
|
||||
fCache := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.Generate;
|
||||
begin
|
||||
fGrammar.Generator.Gen( self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TRuleBlock.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AsString
|
||||
// ============================================================================
|
||||
function TRuleBlock.AsString: AnsiString;
|
||||
begin
|
||||
result := '';
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IAlternativeBlock overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// PrepareForAnalysis
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.PrepareForAnalysis;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
SetLength( fLock, fGrammar.MaxK +1);
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IRuleBlock implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetArguments
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetArguments: AnsiString;
|
||||
begin
|
||||
result := fArguments;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetDefErrorHandler
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetDefErrorHandler: boolean;
|
||||
begin
|
||||
result := fDefErrorHandler;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetEndNode
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetEndNode: IRuleEndElem;
|
||||
begin
|
||||
result := fEndNode;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetIgnoreRule
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetIgnoreRule: AnsiString;
|
||||
begin
|
||||
result := fIgnoreRule;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetLock
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetLock(i: integer): boolean;
|
||||
begin
|
||||
result := fLock[i];
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetCache
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetCache(i: integer): ILookahead;
|
||||
begin
|
||||
result := fCache[i];
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetLabeledElems
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetLabeledElems: TInterfaceList;
|
||||
begin
|
||||
result := fLabeledElems;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetReturnAction
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetReturnAction: AnsiString;
|
||||
begin
|
||||
result := fReturnAction;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetLocals
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetLocals: AnsiString;
|
||||
begin
|
||||
result := fLocals;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetRuleName
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetRuleName: AnsiString;
|
||||
begin
|
||||
result := fRuleName;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetTestLiterals
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetTestLiterals: boolean;
|
||||
begin
|
||||
result := fTestLiterals;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetThrowSpec
|
||||
// ============================================================================
|
||||
function TRuleBlock.GetThrowSpec: AnsiString;
|
||||
begin
|
||||
result := fThrowSpec;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetArguments
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetArguments(pArguments: AnsiString);
|
||||
begin
|
||||
fArguments := pArguments;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetDefErrorHandler
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetDefErrorHandler(pErrorHandler: boolean);
|
||||
begin
|
||||
fDefErrorHandler := pErrorHandler;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetEndNode
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetEndNode(pNode: IRuleEndElem);
|
||||
begin
|
||||
fEndNode := pNode;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetIgnoreRule
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetIgnoreRule(pRule: AnsiString);
|
||||
begin
|
||||
fIgnoreRule := pRule;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetLock
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetLock(i: integer; pLock: boolean);
|
||||
begin
|
||||
fLock[i] := pLock;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetCache
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetCache(i: integer; pCache: ILookahead);
|
||||
begin
|
||||
fCache[i] := pCache;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetLabeledElems
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetLabeledElems(pLabeledElems: TInterfaceList);
|
||||
begin
|
||||
FreeAndNil( fLabeledElems);
|
||||
fLabeledElems := pLabeledElems;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetReturnAction
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetReturnAction(pAction: AnsiString);
|
||||
begin
|
||||
fReturnAction := pAction;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetLocals
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetLocals(pLocals: AnsiString);
|
||||
begin
|
||||
fLocals := pLocals;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetRuleName
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetRuleName(pRuleName: AnsiString);
|
||||
begin
|
||||
fRuleName := pRuleName;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetTestLiterals
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetTestLiterals(pTestLiterals: boolean);
|
||||
begin
|
||||
fTestLiterals := pTestLiterals;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetThrowSpec
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetThrowSpec(pThrowSpec: AnsiString);
|
||||
begin
|
||||
fThrowSpec := pThrowSpec;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AddExceptionSpec
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.AddExceptionSpec( pExceptionSpec: IExceptionSpec);
|
||||
begin
|
||||
(*
|
||||
if FindExceptionSpec( pExceptionSpec.Lbl.TokenText) <> nil then
|
||||
begin
|
||||
if pExceptionSpec.Lbl.TokenText <> '' then
|
||||
fGrammar.Tool.Error( 'Rule "' + fRuleName + '" already has an exception handler for label: ' + pExceptionSpec.Lbl.TokenText,
|
||||
fGrammar.GrammarFile,
|
||||
pExceptionSpec.Lbl.TokenLine,
|
||||
pExceptionSpec.Lbl.TokenColumn)
|
||||
else
|
||||
fGrammar.Tool.Error( 'Rule "' + fRuleName + '" already has an exception handler',
|
||||
fGrammar.GrammarFile,
|
||||
pExceptionSpec.Lbl.TokenLine,
|
||||
pExceptionSpec.Lbl.TokenColumn)
|
||||
end
|
||||
else
|
||||
fExceptionSpecs.Add( pExceptionSpec);
|
||||
*)
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// IsLexerAutoGenRule
|
||||
// ============================================================================
|
||||
function TRuleBlock.IsLexerAutoGenRule: boolean;
|
||||
begin
|
||||
result := (fRuleName = 'nextToken');
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetOption
|
||||
// ============================================================================
|
||||
procedure TRuleBlock.SetOption(pKey, pValue: IToken);
|
||||
var
|
||||
lg: ILexerGrammar;
|
||||
ts: ITokenSymbol;
|
||||
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Dummy if. Needed to help commenting ifs.
|
||||
// ---------------------------------------------------------------
|
||||
if false then
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: defaultErrorHandler
|
||||
// ---------------------------------------------------------------
|
||||
else if pKey.TokenText = 'defaultErrorHandler' then
|
||||
begin
|
||||
if pValue.TokenText = 'true' then
|
||||
fDefErrorHandler := true
|
||||
else if pValue.TokenText = 'false' then
|
||||
fDefErrorHandler := false
|
||||
else
|
||||
fGrammar.Tool.Error( 'Value for "defaultErrorHandler" must be true or false',
|
||||
fGrammar.GrammarFile,
|
||||
pKey.TokenLine,
|
||||
pKey.TokenColumn)
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: testLiterals
|
||||
// ---------------------------------------------------------------
|
||||
else if pKey.TokenText = 'testLiterals' then
|
||||
begin
|
||||
if pValue.TokenText = 'true' then
|
||||
fTestLiterals := true
|
||||
else if pValue.TokenText = 'false' then
|
||||
fTestLiterals := false
|
||||
else
|
||||
fGrammar.Tool.Error( 'Value for "testLiterals" must be true or false',
|
||||
fGrammar.GrammarFile,
|
||||
pKey.TokenLine,
|
||||
pKey.TokenColumn)
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: generateAmbigWarnings
|
||||
// ---------------------------------------------------------------
|
||||
else if pKey.TokenText = 'generateAmbigWarnings' then
|
||||
begin
|
||||
if pValue.TokenText = 'true' then
|
||||
fGenAmbigWarnings := true
|
||||
else if pValue.TokenText = 'false' then
|
||||
fGenAmbigWarnings := false
|
||||
else
|
||||
fGrammar.Tool.Error( 'Value for "generateAmbigWarnings" must be true or false',
|
||||
fGrammar.GrammarFile,
|
||||
pKey.TokenLine,
|
||||
pKey.TokenColumn)
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: ignore
|
||||
// ---------------------------------------------------------------
|
||||
else if pKey.TokenText = 'ignore' then
|
||||
begin
|
||||
if fGrammar.QueryInterface(ILexerGrammar, lg) <> S_OK then
|
||||
fGrammar.Tool.Error( '"Ignore" option only valid for lexer rules',
|
||||
fGrammar.GrammarFile,
|
||||
pKey.TokenLine,
|
||||
pKey.TokenColumn)
|
||||
else
|
||||
fIgnoreRule := pValue.TokenText
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: paraphrase
|
||||
// ---------------------------------------------------------------
|
||||
else if pKey.TokenText = 'paraphrase' then
|
||||
begin
|
||||
if fGrammar.QueryInterface(ILexerGrammar, lg) <> S_OK then
|
||||
fGrammar.Tool.Error( '"Paraphrase" option only valid for lexer rules',
|
||||
fGrammar.GrammarFile,
|
||||
pKey.TokenLine,
|
||||
pKey.TokenColumn)
|
||||
else
|
||||
begin
|
||||
ts := fGrammar.TokenManager.TokenSymbol[fRuleName];
|
||||
|
||||
if ts = nil then
|
||||
fGrammar.Tool.Panic('Cannot find token associated with rule ' + fRuleName)
|
||||
else
|
||||
ts.Paraphrase := pValue.TokenText
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Illegal option
|
||||
// ---------------------------------------------------------------
|
||||
else
|
||||
fGrammar.Tool.Error( Format( MSG_W_ILLEGALRULEOPTION, [pKey.TokenText]),
|
||||
fGrammar.GrammarFile,
|
||||
pKey.TokenLine,
|
||||
pKey.TokenColumn);
|
||||
end;
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Internals
|
||||
// ****************************************************************************
|
||||
function TRuleBlock.GetOneOrMoreBlocks: TInterfaceList;
|
||||
begin
|
||||
result := fOneOrMoreBlocks;
|
||||
end;
|
||||
|
||||
function TRuleBlock.GetNMBlocks : TInterfaceList;
|
||||
begin
|
||||
result := fNMBlocks;
|
||||
end;
|
||||
|
||||
|
||||
function TRuleBlock.GetSynPredBlocks: TInterfaceList;
|
||||
begin
|
||||
result := fSynPredBlocks;
|
||||
end;
|
||||
|
||||
function TRuleBlock.GetExHandlerCode: AnsiString;
|
||||
begin
|
||||
result := fExHandlerCode;
|
||||
end;
|
||||
|
||||
function TRuleBlock.GetExHandlerType: AnsiString;
|
||||
begin
|
||||
result := fExHandlerType;
|
||||
end;
|
||||
|
||||
procedure TRuleBlock.SetExHandlerCode(pExCode: AnsiString);
|
||||
begin
|
||||
fExHandlerCode := pExCode;
|
||||
end;
|
||||
|
||||
procedure TRuleBlock.SetExHandlerType(pExType: AnsiString);
|
||||
begin
|
||||
fExHandlerType := pExType;
|
||||
end;
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user