Initial check in lib
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
bin
|
||||
dcu
|
||||
*.dcu
|
||||
prj.dpgxcon\Win32
|
||||
prj.dpgxcon\Win64
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package mr.dpglib;
|
||||
|
||||
{$R *.res}
|
||||
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
|
||||
{$ALIGN 8}
|
||||
{$ASSERTIONS ON}
|
||||
{$BOOLEVAL OFF}
|
||||
{$DEBUGINFO OFF}
|
||||
{$EXTENDEDSYNTAX ON}
|
||||
{$IMPORTEDDATA ON}
|
||||
{$IOCHECKS ON}
|
||||
{$LOCALSYMBOLS ON}
|
||||
{$LONGSTRINGS ON}
|
||||
{$OPENSTRINGS ON}
|
||||
{$OPTIMIZATION OFF}
|
||||
{$OVERFLOWCHECKS ON}
|
||||
{$RANGECHECKS ON}
|
||||
{$REFERENCEINFO ON}
|
||||
{$SAFEDIVIDE OFF}
|
||||
{$STACKFRAMES ON}
|
||||
{$TYPEDADDRESS OFF}
|
||||
{$VARSTRINGCHECKS ON}
|
||||
{$WRITEABLECONST OFF}
|
||||
{$MINENUMSIZE 1}
|
||||
{$IMAGEBASE $400000}
|
||||
{$DEFINE DEBUG}
|
||||
{$ENDIF IMPLICITBUILDING}
|
||||
{$LIBVERSION '290'}
|
||||
{$IMPLICITBUILD ON}
|
||||
|
||||
requires
|
||||
rtl,
|
||||
mr.dpgrtl;
|
||||
|
||||
contains
|
||||
dpglib.ActionElem in '..\..\src.lib\dpglib.ActionElem.pas',
|
||||
dpglib.Alternative in '..\..\src.lib\dpglib.Alternative.pas',
|
||||
dpglib.AlternativeBlock in '..\..\src.lib\dpglib.AlternativeBlock.pas',
|
||||
dpglib.AlternativeElem in '..\..\src.lib\dpglib.AlternativeElem.pas',
|
||||
dpglib.BlockContext in '..\..\src.lib\dpglib.BlockContext.pas',
|
||||
dpglib.BlockEndElem in '..\..\src.lib\dpglib.BlockEndElem.pas',
|
||||
dpglib.BlockWithImpliedExitPath in '..\..\src.lib\dpglib.BlockWithImpliedExitPath.pas',
|
||||
dpglib.CharLiteralElem in '..\..\src.lib\dpglib.CharLiteralElem.pas',
|
||||
dpglib.CharRangeElem in '..\..\src.lib\dpglib.CharRangeElem.pas',
|
||||
dpglib.CodeGenerator in '..\..\src.lib\dpglib.CodeGenerator.pas',
|
||||
dpglib.DelphiBlockFinishingInfo in '..\..\src.lib\dpglib.DelphiBlockFinishingInfo.pas',
|
||||
dpglib.DelphiCharFormatter in '..\..\src.lib\dpglib.DelphiCharFormatter.pas',
|
||||
dpglib.DelphiGenerator in '..\..\src.lib\dpglib.DelphiGenerator.pas',
|
||||
dpglib.DpgLexer in '..\..\src.lib\dpglib.DpgLexer.pas',
|
||||
dpglib.DpgLexerTokens in '..\..\src.lib\dpglib.DpgLexerTokens.pas',
|
||||
dpglib.DpgParser in '..\..\src.lib\dpglib.DpgParser.pas',
|
||||
dpglib.DpgParserTokens in '..\..\src.lib\dpglib.DpgParserTokens.pas',
|
||||
dpglib.ExceptionHandler in '..\..\src.lib\dpglib.ExceptionHandler.pas',
|
||||
dpglib.ExceptionSpec in '..\..\src.lib\dpglib.ExceptionSpec.pas',
|
||||
dpglib.Grammar in '..\..\src.lib\dpglib.Grammar.pas',
|
||||
dpglib.GrammarAtom in '..\..\src.lib\dpglib.GrammarAtom.pas',
|
||||
dpglib.GrammarBehavior in '..\..\src.lib\dpglib.GrammarBehavior.pas',
|
||||
dpglib.GrammarElem in '..\..\src.lib\dpglib.GrammarElem.pas',
|
||||
dpglib.GrammarMaker in '..\..\src.lib\dpglib.GrammarMaker.pas',
|
||||
dpglib.GrammarSymbol in '..\..\src.lib\dpglib.GrammarSymbol.pas',
|
||||
dpglib.LexerGrammar in '..\..\src.lib\dpglib.LexerGrammar.pas',
|
||||
dpglib.LLkAnalyzer in '..\..\src.lib\dpglib.LLkAnalyzer.pas',
|
||||
dpglib.Lookahead in '..\..\src.lib\dpglib.Lookahead.pas',
|
||||
dpglib.Messages in '..\..\src.lib\dpglib.Messages.pas',
|
||||
dpglib.NMBlock in '..\..\src.lib\dpglib.NMBlock.pas',
|
||||
dpglib.OneOrMoreBlock in '..\..\src.lib\dpglib.OneOrMoreBlock.pas',
|
||||
dpglib.ParserGrammar in '..\..\src.lib\dpglib.ParserGrammar.pas',
|
||||
dpglib.PrettyPrinter in '..\..\src.lib\dpglib.PrettyPrinter.pas',
|
||||
dpglib.RuleBlock in '..\..\src.lib\dpglib.RuleBlock.pas',
|
||||
dpglib.RuleEndElem in '..\..\src.lib\dpglib.RuleEndElem.pas',
|
||||
dpglib.RuleRefElem in '..\..\src.lib\dpglib.RuleRefElem.pas',
|
||||
dpglib.RuleSymbol in '..\..\src.lib\dpglib.RuleSymbol.pas',
|
||||
dpglib.StringLiteralElem in '..\..\src.lib\dpglib.StringLiteralElem.pas',
|
||||
dpglib.StringSymbol in '..\..\src.lib\dpglib.StringSymbol.pas',
|
||||
dpglib.SynPredBlock in '..\..\src.lib\dpglib.SynPredBlock.pas',
|
||||
dpglib.TokenLexer in '..\..\src.lib\dpglib.TokenLexer.pas',
|
||||
dpglib.TokenLexerTokens in '..\..\src.lib\dpglib.TokenLexerTokens.pas',
|
||||
dpglib.TokenManager in '..\..\src.lib\dpglib.TokenManager.pas',
|
||||
dpglib.TokenParser in '..\..\src.lib\dpglib.TokenParser.pas',
|
||||
dpglib.TokenParserTokens in '..\..\src.lib\dpglib.TokenParserTokens.pas',
|
||||
dpglib.TokenRangeElem in '..\..\src.lib\dpglib.TokenRangeElem.pas',
|
||||
dpglib.TokenRefElem in '..\..\src.lib\dpglib.TokenRefElem.pas',
|
||||
dpglib.TokenSymbol in '..\..\src.lib\dpglib.TokenSymbol.pas',
|
||||
dpglib.Tool in '..\..\src.lib\dpglib.Tool.pas',
|
||||
dpglib.TreeBlockContext in '..\..\src.lib\dpglib.TreeBlockContext.pas',
|
||||
dpglib.TreeElem in '..\..\src.lib\dpglib.TreeElem.pas',
|
||||
dpglib.TreeParserGrammar in '..\..\src.lib\dpglib.TreeParserGrammar.pas',
|
||||
dpglib.types in '..\..\src.lib\dpglib.types.pas',
|
||||
dpglib.Utils in '..\..\src.lib\dpglib.Utils.pas',
|
||||
dpglib.Version in '..\..\src.lib\dpglib.Version.pas',
|
||||
dpglib.WildCardElem in '..\..\src.lib\dpglib.WildCardElem.pas',
|
||||
dpglib.ZeroOrMoreBlock in '..\..\src.lib\dpglib.ZeroOrMoreBlock.pas';
|
||||
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
unit dpglib.ActionElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.AlternativeElem;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TActionElem declaration
|
||||
// =========================================================================
|
||||
TActionElem = class( TAlternativeElem,
|
||||
IActionElem,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// Members
|
||||
// ------------------------------------------------------------
|
||||
fActionText : AnsiString;
|
||||
fIsSemPred : boolean;
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ------------------------------------------------------------
|
||||
constructor Create( pGrammar: IGrammar; pToken: IToken);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// IGrammarElem methods
|
||||
// ------------------------------------------------------------
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// IsgpAlternativeElem methods
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// IActionElem methods
|
||||
// ------------------------------------------------------------
|
||||
function GetActionText : AnsiString;
|
||||
function GetSemPred : boolean;
|
||||
|
||||
procedure SetSempred( pSemPred: boolean);
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TActionElem.Create(pGrammar: IGrammar; pToken: IToken);
|
||||
begin
|
||||
inherited Create( pGrammar);
|
||||
|
||||
fActionText := pToken.TokenText;
|
||||
fIsSemPred := false;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IActionElem implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetActionText
|
||||
// ============================================================================
|
||||
function TActionElem.GetActionText: AnsiString;
|
||||
begin
|
||||
result := fActionText;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetSemPred
|
||||
// ============================================================================
|
||||
function TActionElem.GetSemPred: boolean;
|
||||
begin
|
||||
result := fIsSemPred;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetSemPred
|
||||
// ============================================================================
|
||||
procedure TActionElem.SetSempred(pSemPred: boolean);
|
||||
begin
|
||||
fIsSemPred := pSemPred;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TActionElem.Generate;
|
||||
begin
|
||||
fGrammar.Generator.gen( self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TActionElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AsString
|
||||
// ============================================================================
|
||||
function TActionElem.AsString: AnsiString;
|
||||
begin
|
||||
result := ' {' + fActionText;
|
||||
|
||||
if fIsSemPred then
|
||||
result := result + '}?';
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,338 @@
|
||||
unit dpglib.Alternative;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TAlternative declaration
|
||||
// =========================================================================
|
||||
TAlternative = class( TInterfacedObject,
|
||||
IAlternative)
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// Head/Tail of AlternativeElem list
|
||||
// ------------------------------------------------------------
|
||||
fHead : IAlternativeElem;
|
||||
fTail : IAlternativeElem;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// True if AST generation is on for this Alternative.
|
||||
// ------------------------------------------------------------
|
||||
fDoAutoGen : boolean;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Syntactic predicate if any...
|
||||
// ------------------------------------------------------------
|
||||
fSynPredBlock : ISynPredBlock;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Semantic predicate if any...
|
||||
// ------------------------------------------------------------
|
||||
fSemPred : AnsiString;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Exception specification
|
||||
// ------------------------------------------------------------
|
||||
fExHandlerType : AnsiString;
|
||||
fExHandlerCode : AnsiString;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Lookahead for alternative. Filled in by deterministic() only
|
||||
// Used for code gen after calls to deterministic() and used by
|
||||
// deterministic() for (...)*, (...)+ and (...)? blocks. 1..k.
|
||||
// ------------------------------------------------------------
|
||||
fCache : array of ILookahead;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Each alt has different lookahead depth possibly. Depth can
|
||||
// be NONDETERMINISTIC too. 0..n-1.
|
||||
// ------------------------------------------------------------
|
||||
fLookaheadDepth: integer;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Tree specification a'la -> A B C (not implemented)
|
||||
// ------------------------------------------------------------
|
||||
fTreeSpecifier : IToken;
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ------------------------------------------------------------
|
||||
constructor Create; overload;
|
||||
constructor Create( pFirstElem: IAlternativeElem); overload;
|
||||
destructor Destroy; override;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// IAlternative methods
|
||||
// ------------------------------------------------------------
|
||||
protected
|
||||
function GetHead : IAlternativeElem;
|
||||
function GetTail : IAlternativeElem;
|
||||
function GetSynPredBlock : ISynPredBlock;
|
||||
function GetSemPred : AnsiString;
|
||||
|
||||
function GetExHandlerType : AnsiString;
|
||||
function GetExHandlerCode : AnsiString;
|
||||
|
||||
function GetCacheSize : integer;
|
||||
function GetLookaheadDepth : integer;
|
||||
function GetTreeSpecifier : IToken;
|
||||
function GetDoAutoGen : boolean;
|
||||
|
||||
procedure SetHead( pHead : IAlternativeElem);
|
||||
procedure SetTail( pTail : IAlternativeElem);
|
||||
|
||||
procedure SetSynPredBlock( pBlock : ISynPredBlock);
|
||||
procedure SetSemPred( pSemPred : AnsiString);
|
||||
|
||||
procedure SetExHandlerType( pType : AnsiString);
|
||||
procedure SetExHandlerCode( pCode : AnsiString);
|
||||
|
||||
procedure SetCacheSize( pSize : integer);
|
||||
procedure SetLookaheadDepth( pDepth : integer);
|
||||
procedure SetTreeSpecifier( pTreeSpecifier : IToken);
|
||||
procedure SetDoAutoGen( pDoAutoGen : boolean);
|
||||
|
||||
function GetCache( i:integer): ILookahead;
|
||||
procedure SetCache( i: integer; pLookahead: ILookahead);
|
||||
|
||||
public
|
||||
procedure AddElem( pElem: IAlternativeElem);
|
||||
function AtStart: boolean;
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
constructor TAlternative.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
constructor TAlternative.Create(pFirstElem: IAlternativeElem);
|
||||
begin
|
||||
inherited Create;
|
||||
AddElem( pFirstElem);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
// ----------------------------------------------------------------------------
|
||||
destructor TAlternative.Destroy;
|
||||
begin
|
||||
fHead := nil;
|
||||
fTail := nil;
|
||||
fSynPredBlock := nil;
|
||||
fTreeSpecifier := nil;
|
||||
|
||||
//!! fCache := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IAlternative implementation
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetHead
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.GetHead: IAlternativeElem;
|
||||
begin
|
||||
result := fHead;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetTail
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.GetTail: IAlternativeElem;
|
||||
begin
|
||||
result := fTail;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetSynPredBlock
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.GetSynPredBlock: ISynPredBlock;
|
||||
begin
|
||||
result := fSynPredBlock;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetSemPred
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.GetSemPred: AnsiString;
|
||||
begin
|
||||
result := fSemPred;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetCacheSize
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.GetCacheSize: integer;
|
||||
begin
|
||||
result := High(fCache) - Low(fCache);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetCache
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.GetCache(i: integer): ILookahead;
|
||||
begin
|
||||
result := fCache[i];
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetLookaheadDepth
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.GetLookaheadDepth: integer;
|
||||
begin
|
||||
result := fLookaheadDepth;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetTreeSpecifier
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.GetTreeSpecifier: IToken;
|
||||
begin
|
||||
result := fTreeSpecifier;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetAutoGen
|
||||
//
|
||||
// Don't build an AST if there is a tree-rewrite-specifier.
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.GetDoAutoGen: boolean;
|
||||
begin
|
||||
result := fDoAutoGen and (fTreeSpecifier = nil);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetTail
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.SetTail(pTail: IAlternativeElem);
|
||||
begin
|
||||
fTail := pTail;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetHead
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.SetHead(pHead: IAlternativeElem);
|
||||
begin
|
||||
fHead := pHead;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetSynPredBlock
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.SetSynPredBlock(pBlock: ISynPredBlock);
|
||||
begin
|
||||
fSynPredBlock := pBlock;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetSemPred
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.SetSemPred(pSemPred: AnsiString);
|
||||
begin
|
||||
fSemPred := pSemPred;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetCacheSize
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.SetCacheSize(pSize: integer);
|
||||
begin
|
||||
SetLength( fCache, pSize);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetCache
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.SetCache(i: integer; pLookahead: ILookahead);
|
||||
begin
|
||||
fCache[i] := pLookahead;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetLookaheadDepth
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.SetLookaheadDepth(pDepth: integer);
|
||||
begin
|
||||
fLookaheadDepth := pDepth;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetTreeSpecifier
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.SetTreeSpecifier(pTreeSpecifier: IToken);
|
||||
begin
|
||||
fTreeSpecifier := pTreeSpecifier;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetDoAutoGen
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.SetDoAutoGen(pDoAutoGen: boolean);
|
||||
begin
|
||||
fDoAutoGen := pDoAutoGen;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// AddElem
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TAlternative.AddElem(pElem: IAlternativeElem);
|
||||
begin
|
||||
if fHead = nil then
|
||||
begin
|
||||
fHead := pElem;
|
||||
fTail := pElem;
|
||||
end
|
||||
else
|
||||
begin
|
||||
fTail.Next := pElem;
|
||||
fTail := pElem;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// AtStart
|
||||
// ----------------------------------------------------------------------------
|
||||
function TAlternative.AtStart: boolean;
|
||||
begin
|
||||
result := fHead = nil;
|
||||
end;
|
||||
|
||||
function TAlternative.GetExHandlerCode: AnsiString;
|
||||
begin
|
||||
result := fExHandlerCode;
|
||||
end;
|
||||
|
||||
function TAlternative.GetExHandlerType: AnsiString;
|
||||
begin
|
||||
result := fExHandlerType;
|
||||
end;
|
||||
|
||||
procedure TAlternative.SetExHandlerCode(pCode: AnsiString);
|
||||
begin
|
||||
fExHandlerCode := pCode;
|
||||
end;
|
||||
|
||||
procedure TAlternative.SetExHandlerType(pType: AnsiString);
|
||||
begin
|
||||
fExHandlerType := pType;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,610 @@
|
||||
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<fAlternatives.Count) then
|
||||
fAlternatives.Items[i].QueryInterface(IAlternative, result);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetInitAction
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetInitAction(Action: AnsiString);
|
||||
begin
|
||||
fInitAction := Action;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetAlternatives
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetAlternatives(Alts: TInterfaceList);
|
||||
begin
|
||||
fAlternatives.Free;
|
||||
fAlternatives := Alts;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetAutoGen
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetAutoGen(AutoGen: boolean);
|
||||
begin
|
||||
fDoAutoGen := AutoGen;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetNot
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetNot(Invert: boolean);
|
||||
begin
|
||||
fNot := Invert;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetHasASynPred
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetHasASynPred(SynPred: boolean);
|
||||
begin
|
||||
fHasASynPred := SynPred;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetGenAmbigWarnings
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetGenAmbigWarnings(Gen: boolean);
|
||||
begin
|
||||
fGenAmbigWarnings := Gen;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetGreedy
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetGreedy(Greedy: boolean);
|
||||
begin
|
||||
fGreedy := Greedy;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetGreedySet
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetGreedySet(GreedySet: boolean);
|
||||
begin
|
||||
fGreedySet := GreedySet;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetHasAnAction
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetHasAnAction(Action: boolean);
|
||||
begin
|
||||
fHasAnAction := Action;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetWarnFollowAmbig
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetWarnFollowAmbig(Warn: boolean);
|
||||
begin
|
||||
fWarnFollowAmbig := Warn;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetAltI
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetAltI(AltI: integer);
|
||||
begin
|
||||
fAltI := AltI;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetAltJ
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetAltJ(AltJ: integer);
|
||||
begin
|
||||
fAltJ := AltJ;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetAnalyzisAlt
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetAnalyzisAlt(Alt: integer);
|
||||
begin
|
||||
fAnalysisAlt := Alt;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AddAlternative
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.AddAlternative(Alt: IAlternative);
|
||||
begin
|
||||
fAlternatives.Add( Alt);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetOption
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.SetOption(Key, Value: IToken);
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Option: warnWhenFollowAmbig
|
||||
// ---------------------------------------------------------------
|
||||
if Key.TokenText = 'warnWhenFollowAmbig' then
|
||||
begin
|
||||
if Value.TokenText = 'true' then
|
||||
fWarnFollowAmbig := true
|
||||
|
||||
else if Value.TokenText = 'false' then
|
||||
fWarnFollowAmbig := false
|
||||
|
||||
else
|
||||
fGrammar.Tool.Error( 'Value for "warnWhenFollowAmbig" must be true or false',
|
||||
fGrammar.GrammarFile,
|
||||
Key.TokenLine,
|
||||
Key.TokenColumn);
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: generateAmbigWarnings
|
||||
// ---------------------------------------------------------------
|
||||
else if Key.TokenText = 'generateAmbigWarnings' then
|
||||
begin
|
||||
if Value.TokenText = 'true' then
|
||||
fGenAmbigWarnings := true
|
||||
else if Value.TokenText = 'false' then
|
||||
fGenAmbigWarnings := false
|
||||
else
|
||||
fGrammar.Tool.Error( 'Value for "generateAmbigWarnings" must be true or false',
|
||||
fGrammar.GrammarFile,
|
||||
Key.TokenLine,
|
||||
Key.TokenColumn);
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: greedy
|
||||
// ---------------------------------------------------------------
|
||||
else if Key.TokenText = 'greedy' then
|
||||
begin
|
||||
if Value.TokenText = 'true' then
|
||||
begin
|
||||
fGreedy := true;
|
||||
fGreedySet := true;
|
||||
end
|
||||
else if Value.TokenText = 'false' then
|
||||
begin
|
||||
fGreedy := false;
|
||||
fGreedySet := true;
|
||||
end
|
||||
else
|
||||
fGrammar.Tool.Error( 'Value for "greedy" must be true or false',
|
||||
fGrammar.GrammarFile,
|
||||
Key.TokenLine,
|
||||
Key.TokenColumn);
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Invalid option
|
||||
// ---------------------------------------------------------------
|
||||
else
|
||||
begin
|
||||
fGrammar.Tool.Error( 'Invalid subrule option: "' + Key.TokenText + '"',
|
||||
fGrammar.GrammarFile,
|
||||
Key.TokenLine,
|
||||
Key.TokenColumn);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// PrepareForAnalysis
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.PrepareForAnalysis;
|
||||
var
|
||||
i: integer;
|
||||
a: IAlternative;
|
||||
|
||||
begin
|
||||
for i:=0 to fAlternatives.Count -1 do
|
||||
begin
|
||||
// ------------------------------------------------------------
|
||||
// Deterministic() uses an alternative cache and sets lookahead
|
||||
// depth.
|
||||
// ------------------------------------------------------------
|
||||
if fAlternatives.Items[i].QueryInterface( IAlternative, a) = S_OK then
|
||||
begin
|
||||
a.CacheSize := fGrammar.MaxK + 1;
|
||||
a.LookaheadDepth := LOOKAHEAD_DEPTH_INIT;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// RemoveTracking
|
||||
//
|
||||
// Walk the syntactic predicate and, for a rule ref R, remove the ref from the
|
||||
// list of FOLLOW references for R (stored in the symbol table).
|
||||
// ============================================================================
|
||||
procedure TAlternativeBlock.RemoveTracking(Grammar: IGrammar);
|
||||
var
|
||||
i : integer;
|
||||
alt : IAlternative;
|
||||
elem : IAlternativeElem;
|
||||
ab : IAlternativeBlock;
|
||||
rr : IRuleRefElem;
|
||||
rs : IRuleSymbol;
|
||||
|
||||
begin
|
||||
for i:=0 to fAlternatives.Count-1 do
|
||||
begin
|
||||
fAlternatives.Items[i].QueryInterface(IAlternative,alt);
|
||||
elem := alt.Head;
|
||||
|
||||
while elem <> 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.
|
||||
@@ -0,0 +1,157 @@
|
||||
unit dpglib.AlternativeElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.GrammarElem;
|
||||
|
||||
type
|
||||
TAlternativeElem = class( TGrammarElem, IAlternativeElem, IGrammarElem)
|
||||
protected
|
||||
fNext : IAlternativeElem;
|
||||
fEnclosingRule : AnsiString;
|
||||
fAutoGenType : integer;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
constructor Create( Grammar : IGrammar); overload;
|
||||
constructor Create( Grammar : IGrammar;
|
||||
Start : IToken); overload;
|
||||
constructor Create( Grammar : IGrammar;
|
||||
Start : IToken;
|
||||
AutoGenType : integer); overload;
|
||||
|
||||
destructor Destroy; override;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IAlternativeElem
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function GetAutoGenType : integer;
|
||||
function GetNext : IAlternativeElem;
|
||||
function GetLabel : AnsiString;
|
||||
function GetEnclosingRule : AnsiString;
|
||||
|
||||
procedure SetNext( Next : IAlternativeElem);
|
||||
procedure SetLabel( Lbl : AnsiString);
|
||||
procedure SetEnclosingRule( Rule : AnsiString);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TAlternativeElem.Create( Grammar: IGrammar);
|
||||
begin
|
||||
inherited Create( Grammar);
|
||||
fAutoGenType := AUTOGEN_NONE;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TAlternativeElem.Create( Grammar : IGrammar;
|
||||
Start : IToken);
|
||||
begin
|
||||
inherited Create( Grammar, Start);
|
||||
fAutoGenType := AUTOGEN_NONE;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TAlternativeElem.Create( Grammar : IGrammar;
|
||||
Start : IToken;
|
||||
AutoGenType: integer);
|
||||
begin
|
||||
inherited Create( Grammar, Start);
|
||||
fAutoGenType := AutoGenType;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Destructor
|
||||
// ================================================================================================
|
||||
destructor TAlternativeElem.Destroy;
|
||||
begin
|
||||
fNext := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// @@@: IAlternativeElem implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IAlternativeElem implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get AutoGenType
|
||||
// ================================================================================================
|
||||
function TAlternativeElem.GetAutoGenType: integer;
|
||||
begin
|
||||
result := fAutoGenType;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get EnclosingRule
|
||||
// ================================================================================================
|
||||
function TAlternativeElem.GetEnclosingRule: AnsiString;
|
||||
begin
|
||||
result := fEnclosingRule;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Label
|
||||
// ================================================================================================
|
||||
function TAlternativeElem.GetLabel: AnsiString;
|
||||
begin
|
||||
result := '';
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Next
|
||||
// ================================================================================================
|
||||
function TAlternativeElem.GetNext: IAlternativeElem;
|
||||
begin
|
||||
result := fNext;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set EnclosingRule
|
||||
// ================================================================================================
|
||||
procedure TAlternativeElem.SetEnclosingRule(Rule: AnsiString);
|
||||
begin
|
||||
fEnclosingRule := Rule;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Label
|
||||
// ================================================================================================
|
||||
procedure TAlternativeElem.SetLabel(Lbl: AnsiString);
|
||||
begin
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Next
|
||||
// ================================================================================================
|
||||
procedure TAlternativeElem.SetNext(Next: IAlternativeElem);
|
||||
begin
|
||||
fNext := Next;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,57 @@
|
||||
// ================================================================================================
|
||||
// BlockContext stores the information needed when creating an alternative (list of elements).
|
||||
// Entering a subrule requires that we save this state as each block of alternatives requires
|
||||
// state such as "tail of current alternative."
|
||||
// ================================================================================================
|
||||
unit dpglib.BlockContext;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpglib.types;
|
||||
|
||||
type
|
||||
TBlockContext = class(TObject)
|
||||
private
|
||||
fAltNum : integer;
|
||||
fBlock : IAlternativeBlock;
|
||||
fBlockEnd : IBlockEndElem;
|
||||
|
||||
public
|
||||
procedure AddAlternativeElem( pElem: IAlternativeElem); virtual;
|
||||
|
||||
function CurrentAlt : IAlternative;
|
||||
function CurrentElem : IAlternativeElem;
|
||||
|
||||
public
|
||||
property AltNum : integer read fAltNum write fAltNum;
|
||||
property Block : IAlternativeBlock read fBlock write fBlock;
|
||||
property BlockEnd : IBlockEndElem read fBlockEnd write fBlockEnd;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
// CurrentAlt
|
||||
// ----------------------------------------------------------------------------
|
||||
function TBlockContext.CurrentAlt: IAlternative;
|
||||
begin
|
||||
fBlock.Alternatives.Items[fAltNum].QueryInterface( IAlternative, result);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CurrentElem
|
||||
// ----------------------------------------------------------------------------
|
||||
function TBlockContext.CurrentElem: IAlternativeElem;
|
||||
begin
|
||||
result := CurrentAlt.Tail;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// AddAlternativeElem
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TBlockContext.AddAlternativeElem(pElem: IAlternativeElem);
|
||||
begin
|
||||
CurrentAlt.AddElem( pElem);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,130 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// All alternative blocks are "terminated" by BlockEndElements unless theye are
|
||||
// rule blocks (in which case they use RuleEndElement).
|
||||
// ----------------------------------------------------------------------------
|
||||
unit dpglib.BlockEndElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpglib.types,
|
||||
dpglib.AlternativeElem;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TBlockEndElem declaration
|
||||
// =========================================================================
|
||||
TBlockEndElem = class( TAlternativeElem,
|
||||
IBlockEndElem,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fLock : array of boolean;
|
||||
fBlock : IAlternativeBlock;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar: IGrammar);
|
||||
destructor Destroy; override;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString: AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IBlockEndElem methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetBlock: IAlternativeBlock;
|
||||
function GetLock( i: integer): boolean;
|
||||
|
||||
procedure SetBlock( pBlock: IAlternativeBlock);
|
||||
procedure SetLock( i: integer; pLock: boolean);
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TBlockEndElem.Create(pGrammar: IGrammar);
|
||||
begin
|
||||
inherited Create( pGrammar);
|
||||
SetLength( fLock, pGrammar.MaxK + 1);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TBlockEndElem.Destroy;
|
||||
begin
|
||||
fLock := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TBlockEndElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AsString
|
||||
// ============================================================================
|
||||
function TBlockEndElem.AsString: AnsiString;
|
||||
begin
|
||||
result := ' [BlkEnd]';
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IBlockEndElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetBlock
|
||||
// ============================================================================
|
||||
function TBlockEndElem.GetBlock: IAlternativeBlock;
|
||||
begin
|
||||
result := fBlock;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetLock
|
||||
// ============================================================================
|
||||
function TBlockEndElem.GetLock(i: integer): boolean;
|
||||
begin
|
||||
Result := fLock[i];
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetBlock
|
||||
// ============================================================================
|
||||
procedure TBlockEndElem.SetBlock(pBlock: IAlternativeBlock);
|
||||
begin
|
||||
fBlock := pBlock;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetLock
|
||||
// ============================================================================
|
||||
procedure TBlockEndElem.SetLock(i: integer; pLock: boolean);
|
||||
begin
|
||||
fLock[i] := pLock;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,120 @@
|
||||
unit dpglib.BlockWithImpliedExitPath;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.AlternativeBlock;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TBlockWithImpliedExitPath declaration
|
||||
// =========================================================================
|
||||
TBlockWithImpliedExitPath = class( TAlternativeBlock,
|
||||
IBlockWithImpliedExitPath,
|
||||
IAlternativeBlock,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fExitLookaheadDepth : integer;
|
||||
fExitCache : array of ILookahead;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar: IGrammar); overload;
|
||||
constructor Create( pGrammar: IGrammar; pStart: IToken); overload;
|
||||
destructor Destroy; override;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IBlockWithImpliedExitPath methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetExitDepth: integer;
|
||||
function GetExitCache( i: integer) : ILookahead;
|
||||
|
||||
procedure SetExitDepth( pDepth: integer);
|
||||
procedure SetExitCache( i: integer; pExitCache: ILookahead);
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TBlockWithImpliedExitPath.Create( pGrammar : IGrammar);
|
||||
begin
|
||||
inherited Create( pGrammar);
|
||||
SetLength( fExitCache, pGrammar.MaxK + 1);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TBlockWithImpliedExitPath.Create( pGrammar : IGrammar;
|
||||
pStart : IToken);
|
||||
begin
|
||||
inherited Create( pGrammar, pStart);
|
||||
SetLength( fExitCache, pGrammar.MaxK + 1);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TBlockWithImpliedExitPath.Destroy;
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
for i:=Low(fExitCache) to High(fExitCache) do
|
||||
fExitCache[i] := nil;
|
||||
|
||||
fExitCache := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IBlockWithImpliedExitPath implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetExitDepth
|
||||
// ============================================================================
|
||||
function TBlockWithImpliedExitPath.GetExitDepth: integer;
|
||||
begin
|
||||
result := fExitLookaheadDepth;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetExitCache
|
||||
// ============================================================================
|
||||
function TBlockWithImpliedExitPath.GetExitCache( i: integer): ILookahead;
|
||||
begin
|
||||
result := fExitCache[i];
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetExitDepth
|
||||
// ============================================================================
|
||||
procedure TBlockWithImpliedExitPath.SetExitDepth(pDepth: integer);
|
||||
begin
|
||||
fExitLookaheadDepth := pDepth;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetExitCache
|
||||
// ============================================================================
|
||||
procedure TBlockWithImpliedExitPath.SetExitCache( i : integer;
|
||||
pExitCache : ILookahead);
|
||||
begin
|
||||
fExitCache[i] := pExitCache;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,88 @@
|
||||
unit dpglib.CharLiteralElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.GrammarAtom;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TCharLiteralElem declaration
|
||||
// =========================================================================
|
||||
TCharLiteralElem = class( TGrammarAtom,
|
||||
ICharLiteralElem,
|
||||
IGrammarAtom,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ------------------------------------------------------------
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pInverted : boolean;
|
||||
pAutoGenType: integer);
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// IGrammarElem methods
|
||||
// ------------------------------------------------------------
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
end;
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
constructor TCharLiteralElem.Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pInverted : boolean;
|
||||
pAutoGenType: integer);
|
||||
begin
|
||||
inherited Create( pGrammar, pToken, AUTOGEN_NONE);
|
||||
|
||||
{ TODO 1 -omiki -ctoken : Fix for TokenTypeForCharLiteral }
|
||||
if pToken.TokenText = '' then
|
||||
begin
|
||||
fLine := 1;
|
||||
exit;
|
||||
end;
|
||||
|
||||
fTokenType := ord(pToken.TokenText[1]);
|
||||
// token_type = ANTLRLexer.tokentypeforcharliteral(pToken.TokenText);
|
||||
// pGrammar.charVocabulary.add fTokenType;
|
||||
|
||||
fLine := pToken.TokenLine;
|
||||
fNot := pInverted;
|
||||
fAutoGenType:= pAutoGenType;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem implementation
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// Generate
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TCharLiteralElem.Generate;
|
||||
var
|
||||
elem: ICharLiteralElem;
|
||||
|
||||
begin
|
||||
elem := self;
|
||||
fGrammar.Generator.Gen(elem);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Look
|
||||
// ----------------------------------------------------------------------------
|
||||
function TCharLiteralElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,163 @@
|
||||
unit dpglib.CharRangeElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.AlternativeElem;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TCharRangeElem declaration
|
||||
// =========================================================================
|
||||
TCharRangeElem = class( TAlternativeElem,
|
||||
ICharRangeElem,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fLabel : AnsiString;
|
||||
fBegin : AnsiChar;
|
||||
fEnd : AnsiChar;
|
||||
fBeginText : AnsiString;
|
||||
fEndText : AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pToken1 : IToken;
|
||||
pToken2 : IToken;
|
||||
pAutoGenType : integer);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IAlternativeElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetLabel : AnsiString;
|
||||
procedure SetLabel( pLabel: AnsiString);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// ICharRangeElem methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetBeginChar : AnsiChar;
|
||||
function GetEndChar : AnsiChar;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TCharRangeElem.Create( pGrammar : IGrammar;
|
||||
pToken1 : IToken;
|
||||
pToken2 : IToken;
|
||||
pAutoGenType: integer);
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
inherited Create( pGrammar, pToken1);
|
||||
|
||||
fBegin := pToken1.TokenText[1];
|
||||
fEnd := pToken2.TokenText[1];
|
||||
|
||||
fBeginText := pToken1.TokenText;
|
||||
fEndText := pToken2.TokenText;
|
||||
|
||||
fAutoGenType:= pAutoGenType;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Track which AnsiCharacters are referenced in the grammar.
|
||||
// ---------------------------------------------------------------
|
||||
for i:=ord( fBegin) to ord( fEnd) do
|
||||
; // fGrammar.charVocabulary.add(i)
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem ovrrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TCharRangeElem.Generate;
|
||||
begin
|
||||
fGrammar.Generator.gen( self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TCharRangeElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AsString
|
||||
// ============================================================================
|
||||
function TCharRangeElem.AsString: AnsiString;
|
||||
begin
|
||||
if fLabel <> '' then
|
||||
result := ' ' + fLabel + ':' + fBeginText + '..' + fEndText
|
||||
else
|
||||
result := ' ' + fBeginText + '..' + fEndText;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IAlternativeElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetLabel
|
||||
// ============================================================================
|
||||
function TCharRangeElem.GetLabel: AnsiString;
|
||||
begin
|
||||
result := fLabel;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetLabel
|
||||
// ============================================================================
|
||||
procedure TCharRangeElem.SetLabel(pLabel: AnsiString);
|
||||
begin
|
||||
fLabel := pLabel;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// ICharRangeElem implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetBeginChar
|
||||
// ============================================================================
|
||||
function TCharRangeElem.GetBeginChar: AnsiChar;
|
||||
begin
|
||||
result := fBegin;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetEndChar
|
||||
// ============================================================================
|
||||
function TCharRangeElem.GetEndChar: AnsiChar;
|
||||
begin
|
||||
result := fEnd;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,588 @@
|
||||
// ============================================================================
|
||||
// A CodeGenerator knows about a Grammar data structure and
|
||||
// a grammar analyzer. The Grammar is walked to generate the
|
||||
// appropriate code for both a parser and lexer (if present).
|
||||
// This interface may change slightly so that the lexer is
|
||||
// itself living inside of a Grammar object (in which case,
|
||||
// this class generates only one recognizer). The main method
|
||||
// to call is <tt>gen()</tt>, which initiates all code gen.
|
||||
//
|
||||
// The interaction of the code generator with the analyzer is
|
||||
// simple: each subrule block calls deterministic() before generating
|
||||
// code for the block. Method deterministic() sets lookahead caches
|
||||
// in each Alternative object. Technically, a code generator
|
||||
// doesn't need the grammar analyzer if all lookahead analysis
|
||||
// is done at runtime, but this would result in a slower parser.
|
||||
//
|
||||
// This class provides a set of support utilities to handle argument
|
||||
// list parsing and so on.
|
||||
// ============================================================================
|
||||
unit dpglib.CodeGenerator;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
dpgrtl.types,
|
||||
dpglib.types;
|
||||
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// TCodeGenerator
|
||||
// =========================================================================
|
||||
TCodeGenerator = class( TInterfacedObject,
|
||||
ICodeGenerator)
|
||||
// ------------------------------------------------------------
|
||||
// class functions (statics)
|
||||
// ------------------------------------------------------------
|
||||
class function encodeLexerRuleName( pName: AnsiString): AnsiString;
|
||||
class function decodeLexerRuleName( pName: AnsiString): AnsiString;
|
||||
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// Members
|
||||
// ------------------------------------------------------------
|
||||
fGrammar : IGrammar;
|
||||
fTool : ITool;
|
||||
fAnalyzer : ILLkAnalyzer;
|
||||
fBehavior : IGrammarBehavior;
|
||||
fCharFormatter : ICharFormatter;
|
||||
|
||||
fFile : AnsiString;
|
||||
fOutput : TStream;
|
||||
|
||||
fTabs : integer;
|
||||
fBitsetUsed : TByteSet;
|
||||
|
||||
DEBUG_GEN : boolean;
|
||||
|
||||
fTab : AnsiString; // Tab sequence
|
||||
fTokenTypesFileSuffix : AnsiString; // Token exchange file suffix
|
||||
fTokenTypesFileExt : AnsiString; // Token exchange file extension
|
||||
|
||||
fLitPrefix : AnsiString; // Literal prefix
|
||||
fTokPrefix : AnsiString; // Token prefix
|
||||
|
||||
fOutDir : AnsiString; // Output directory
|
||||
fExcDir : AnsiString; // Token exchange dir
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ------------------------------------------------------------
|
||||
constructor Create( OutputDir: AnsiString;
|
||||
ExchangeDir: AnsiString);
|
||||
destructor Destroy; override;
|
||||
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// Internals
|
||||
// ------------------------------------------------------------
|
||||
procedure indent;
|
||||
procedure _print( pString : AnsiString);
|
||||
procedure _println( pString : AnsiString);
|
||||
procedure print( pString : AnsiString);
|
||||
procedure println( pString : AnsiString);
|
||||
procedure printAction( pString : AnsiString);
|
||||
|
||||
procedure untabifyLines( pStrings : TStringList);
|
||||
procedure indentLines( pStrings : TStringList);
|
||||
|
||||
procedure genTokenExchange;
|
||||
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// ICodeGenerator methods
|
||||
// ------------------------------------------------------------
|
||||
procedure Gen(pGrammar: IGrammar); overload; virtual;
|
||||
// procedure Gen(pGrammar: ILexerGrammar); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IActionElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IAlternativeBlock); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IBlockEndElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : ICharLiteralElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : ICharRangeElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IGrammarAtom); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IOneOrMoreBlock); overload; virtual; abstract;
|
||||
procedure Gen(pElem : INMBlock); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IRuleBlock); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IRuleEndElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IRuleRefElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IStringLiteralElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : ISynPredBlock); overload; virtual; abstract;
|
||||
procedure Gen(pElem : ITokenRefElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : ITokenRangeElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : ITreeElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IWildCardElem); overload; virtual; abstract;
|
||||
procedure Gen(pElem : IZeroOrMoreBlock); overload; virtual; abstract;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpglib.utils,
|
||||
System.SysUtils,
|
||||
System.StrUtils;
|
||||
|
||||
// ****************************************************************************
|
||||
//
|
||||
// Coonstructor/destructor
|
||||
//
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TCodeGenerator.Create( OutputDir : AnsiString;
|
||||
ExchangeDir : AnsiString);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fTab := ' ';
|
||||
fTabs := 0;
|
||||
|
||||
fOutDir := OutputDir;
|
||||
fExcDir := ExchangeDir;
|
||||
|
||||
if fOutDir <> '' then if fOutDir[Length(fOutDir)] <> '\' then fOutDir := fOutDir + '\';
|
||||
if fExcDir <> '' then if fExcDir[Length(fExcDir)] <> '\' then fExcDir := fExcDir + '\';
|
||||
|
||||
fTokenTypesFileSuffix := 'Tokens';
|
||||
fTokenTypesFileExt := '.txt';
|
||||
|
||||
fTokPrefix := 'TT_';
|
||||
fLitPrefix := 'LT_';
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TCodeGenerator.Destroy;
|
||||
begin
|
||||
fGrammar := nil;
|
||||
fTool := nil;
|
||||
fAnalyzer := nil;
|
||||
fBehavior := nil;
|
||||
fCharFormatter := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
//
|
||||
// ICodeGenerator implementation
|
||||
//
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Gen
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator.Gen(pGrammar: IGrammar);
|
||||
begin
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
//
|
||||
// Internal utility methods
|
||||
//
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Indent
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator.indent;
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
for i:=1 to fTabs do
|
||||
_print( fTab);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// _print
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator._print(pString: AnsiString);
|
||||
begin
|
||||
if pString = '' then
|
||||
pString := ' ';
|
||||
|
||||
fOutput.Write( pString[1], Length(pString));
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// _println
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator._println(pString: AnsiString);
|
||||
begin
|
||||
_print( pString);
|
||||
_print( #13+#10);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// print
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator.print(pString: AnsiString);
|
||||
begin
|
||||
indent;
|
||||
_print( pString);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// prinln
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator.println(pString: AnsiString);
|
||||
begin
|
||||
indent;
|
||||
_println( pString);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// printAction
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator.printAction(pString: AnsiString);
|
||||
var
|
||||
i : integer;
|
||||
len : integer;
|
||||
indent: integer;
|
||||
|
||||
stm : TStringStream;
|
||||
lines : TStringList;
|
||||
line : AnsiString;
|
||||
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Remove the '{' and '}' or '[' and ']' characters from the
|
||||
// beginning and from the end.
|
||||
// ---------------------------------------------------------------
|
||||
pString := Trim( pString);
|
||||
pString := Copy(pString,2,Length(pString)-2);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Make AnsiStringlist from the action text.
|
||||
// ---------------------------------------------------------------
|
||||
len := 0;
|
||||
stm := TStringStream.Create( pString);
|
||||
lines := TStringList.Create;
|
||||
lines.LoadFromStream( stm);
|
||||
stm.Free;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Check that the line with the opening bracket (ie. the first)
|
||||
// has code or not.
|
||||
// ---------------------------------------------------------------
|
||||
if Trim(lines.Strings[0]) = '' then
|
||||
indent := 0
|
||||
else
|
||||
indent := 1;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Remove empty lines from the beginning
|
||||
// ---------------------------------------------------------------
|
||||
while lines.Count > 0 do
|
||||
begin
|
||||
if Trim(lines.Strings[0]) = '' then
|
||||
lines.Delete(0)
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Remove empty lines from the end
|
||||
// ---------------------------------------------------------------
|
||||
while lines.Count > 0 do
|
||||
begin
|
||||
if Trim( lines.Strings[lines.Count-1]) = '' then
|
||||
lines.Delete(lines.Count-1)
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// If there is a TAB character in the action AnsiString, then simply
|
||||
// emit the AnsiString. Later we can format this too, but not yet.
|
||||
// ---------------------------------------------------------------
|
||||
untabifyLines( lines);
|
||||
indentLines( lines);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Print out the lines, but calculate the indent value
|
||||
// ------------------------------------------------------------
|
||||
for i:=0 to lines.Count-1 do
|
||||
begin
|
||||
line := lines.Strings[i];
|
||||
println(line);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genTokenExchange
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator.genTokenExchange;
|
||||
var
|
||||
i : integer;
|
||||
fName : AnsiString;
|
||||
name : AnsiString;
|
||||
value : AnsiString;
|
||||
ts : ITokenSymbol;
|
||||
ss : IStringSymbol;
|
||||
pTM : ITokenManager;
|
||||
|
||||
begin
|
||||
if fGrammar.ExportVocab = '' then
|
||||
fGrammar.ExportVocab := fGrammar.UnitName;
|
||||
|
||||
fName := fExcDir +
|
||||
fGrammar.ExportVocab +
|
||||
fTokenTypesFileSuffix +
|
||||
fTokenTypesFileExt;
|
||||
|
||||
try
|
||||
pTM := fGrammar.TokenManager;
|
||||
fOutput := TFileStream.Create( fName, fmCreate);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Header
|
||||
// ------------------------------------------------------------
|
||||
println( '// $Delphi Parser Generator: ' +
|
||||
ExtractFileName( fGrammar.GrammarFile) +
|
||||
' -> ' +
|
||||
fGrammar.GrammarFile +
|
||||
fTokenTypesFileSuffix +
|
||||
fTokenTypesFileExt +
|
||||
'$');
|
||||
|
||||
fTabs := 0;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Header grammar name
|
||||
// ------------------------------------------------------------
|
||||
println( fGrammar.GetClassName);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Generate a definition to for each token type.
|
||||
// ------------------------------------------------------------
|
||||
for name in pTM.Vocabulary.Keys do
|
||||
begin
|
||||
value := IntToStr(pTM.Vocabulary.Items[name]);
|
||||
ts := pTM.TokenSymbol[name];
|
||||
ss := nil;
|
||||
|
||||
if ts <> nil then
|
||||
ts.QueryInterface( IStringSymbol, ss);
|
||||
|
||||
if name[1] <> '<' then
|
||||
begin
|
||||
// ------------------------------------------------------
|
||||
// Handle AnsiString symbols.
|
||||
// ------------------------------------------------------
|
||||
if name[1] = '"' then
|
||||
begin
|
||||
if ss <> nil then
|
||||
begin
|
||||
if ss.Lbl = '' then
|
||||
begin
|
||||
ss.Lbl := fLitPrefix + StringToID( Copy( name, 2, Length(name)-2));
|
||||
|
||||
// ss.Lbl := fLitPrefix + Copy( name, 2, Length(name)-2);
|
||||
//
|
||||
// ss.Lbl := AnsiReplaceStr( ss.LBL, '$', '_DOLLAR_');
|
||||
// ss.Lbl := AnsiReplaceStr( ss.LBL, '/', '_SLASH_');
|
||||
// ss.Lbl := AnsiReplaceStr( ss.LBL, ':', '_COLON_');
|
||||
// ss.Lbl := AnsiReplaceStr( ss.LBL, '.', '_DOT_');
|
||||
|
||||
ss.LBL := AnsiReplaceStr( ss.LBL, 'LT__', 'LT_');
|
||||
end;
|
||||
|
||||
println( ss.Lbl + '=' + name + '=' + value);
|
||||
end;
|
||||
end
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Handle token symbols.
|
||||
// ------------------------------------------------------
|
||||
else
|
||||
begin
|
||||
if ts <> nil then
|
||||
begin
|
||||
print( fTokPrefix + name);
|
||||
|
||||
if ts.Paraphrase <> '' then
|
||||
_print( '(' + ts.Paraphrase + ')');
|
||||
|
||||
_println( '=' + value);
|
||||
end
|
||||
// else
|
||||
// fGrammar.Tool.Error( 'Undefined token symbol' + name);
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
(*
|
||||
for i:=0 to pTM.Vocabulary.Count -1 do
|
||||
begin
|
||||
name := pTM.Vocabulary.Names[i];
|
||||
value := pTM.Vocabulary.Values[name];
|
||||
ts := pTM.TokenSymbol[name];
|
||||
ss := nil;
|
||||
|
||||
if ts <> nil then
|
||||
ts.QueryInterface( IStringSymbol, ss);
|
||||
|
||||
if name[1] <> '<' then
|
||||
begin
|
||||
// ------------------------------------------------------
|
||||
// Handle AnsiString symbols.
|
||||
// ------------------------------------------------------
|
||||
if name[1] = '"' then
|
||||
begin
|
||||
if ss <> nil then
|
||||
begin
|
||||
if ss.Lbl = '' then
|
||||
begin
|
||||
ss.Lbl := fLitPrefix + StringToID( Copy( name, 2, Length(name)-2));
|
||||
|
||||
// ss.Lbl := fLitPrefix + Copy( name, 2, Length(name)-2);
|
||||
//
|
||||
// ss.Lbl := AnsiReplaceStr( ss.LBL, '$', '_DOLLAR_');
|
||||
// ss.Lbl := AnsiReplaceStr( ss.LBL, '/', '_SLASH_');
|
||||
// ss.Lbl := AnsiReplaceStr( ss.LBL, ':', '_COLON_');
|
||||
// ss.Lbl := AnsiReplaceStr( ss.LBL, '.', '_DOT_');
|
||||
|
||||
ss.LBL := AnsiReplaceStr( ss.LBL, 'LT__', 'LT_');
|
||||
end;
|
||||
|
||||
println( ss.Lbl + '=' + name + '=' + value);
|
||||
end;
|
||||
end
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Handle token symbols.
|
||||
// ------------------------------------------------------
|
||||
else
|
||||
begin
|
||||
if ts <> nil then
|
||||
begin
|
||||
print( fTokPrefix + name);
|
||||
|
||||
if ts.Paraphrase <> '' then
|
||||
_print( '(' + ts.Paraphrase + ')');
|
||||
|
||||
_println( '=' + value);
|
||||
end
|
||||
// else
|
||||
// fGrammar.Tool.Error( 'Undefined token symbol' + name);
|
||||
end
|
||||
end
|
||||
end
|
||||
*)
|
||||
finally
|
||||
if fOutput <> nil then
|
||||
FreeAndNil( fOutput);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// encodeLexerRuleName
|
||||
// ============================================================================
|
||||
class function TCodeGenerator.encodeLexerRuleName( pName: AnsiString): AnsiString;
|
||||
begin
|
||||
result := 'm' + pName;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// encodeLexerRuleName
|
||||
// ============================================================================
|
||||
class function TCodeGenerator.decodeLexerRuleName( pName: AnsiString): AnsiString;
|
||||
begin
|
||||
if pName[1] = 'm' then
|
||||
result := Copy( pName, 2, Length(pName) -1)
|
||||
else
|
||||
result := pName;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// indent
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator.indentLines(pStrings: TStringList);
|
||||
var
|
||||
minLead : integer;
|
||||
i : integer;
|
||||
lead : integer;
|
||||
s : AnsiString;
|
||||
|
||||
begin
|
||||
if pStrings.Count = 1 then
|
||||
begin
|
||||
pStrings.Strings[0] := Trim( pStrings.Strings[0]);
|
||||
exit;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// search for the shortest leading size.
|
||||
// ---------------------------------------------------------------
|
||||
minLead := 1000;
|
||||
|
||||
for i:=0 to pStrings.Count -1 do
|
||||
begin
|
||||
s := pStrings.Strings[i];
|
||||
lead := Length(s) - Length( TrimLeft( s));
|
||||
|
||||
if Trim(s) <> '' then
|
||||
if minLead > lead then
|
||||
minLead := lead;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Now shorten the lines
|
||||
// ---------------------------------------------------------------
|
||||
for i:=0 to pStrings.Count -1 do
|
||||
begin
|
||||
s := pStrings.Strings[i];
|
||||
s := Copy( s, minLead +1, length(s));
|
||||
pStrings.Strings[i] := s;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// untabify
|
||||
// ============================================================================
|
||||
procedure TCodeGenerator.untabifyLines(pStrings: TStringList);
|
||||
var
|
||||
i: integer;
|
||||
j: integer;
|
||||
k: integer;
|
||||
l: integer;
|
||||
p: integer;
|
||||
s: AnsiString;
|
||||
x: AnsiString;
|
||||
|
||||
begin
|
||||
l := Length( fTab);
|
||||
|
||||
for i:=0 to pStrings.Count -1 do
|
||||
begin
|
||||
s := TrimRight(pStrings.Strings[i]);
|
||||
pStrings.Strings[i] := s;
|
||||
|
||||
|
||||
if pos( #9, s) > 0 then
|
||||
begin
|
||||
x := '';
|
||||
|
||||
for j:=1 to Length(s) do
|
||||
begin
|
||||
if s[j] <> #9 then
|
||||
begin
|
||||
x := x + s[j];
|
||||
end
|
||||
else
|
||||
begin
|
||||
p := l - (Length(x) mod l);
|
||||
|
||||
for k:=1 to p do
|
||||
x := x + ' ';
|
||||
end;
|
||||
end;
|
||||
|
||||
pStrings.Strings[i] := x;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,60 @@
|
||||
unit dpglib.DelphiBlockFinishingInfo;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes;
|
||||
|
||||
type
|
||||
TDelphiBlockFinishingInfo = class
|
||||
public
|
||||
PostScript : AnsiString;
|
||||
GeneratedSwitch : boolean;
|
||||
GeneratedAnIf : boolean;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// When generating an if or switch, end-of-token lookahead sets
|
||||
// will become the else or default clause, don't generate an
|
||||
// error clause in this case.
|
||||
// ------------------------------------------------------------
|
||||
NeedAnErrorClause : boolean;
|
||||
NeedAClosingEnd : boolean;
|
||||
|
||||
public
|
||||
constructor Create; overload;
|
||||
constructor Create( pPostScript : AnsiString;
|
||||
pGenSwitch : boolean;
|
||||
pGenAnIf : boolean;
|
||||
pNeedEC : boolean); overload;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TDelphiBlockFinishingInfo }
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TDelphiBlockFinishingInfo.Create;
|
||||
begin
|
||||
PostScript := '';
|
||||
GeneratedSwitch := false;
|
||||
GeneratedAnIf := false;
|
||||
NeedAnErrorClause := true;
|
||||
NeedAClosingEnd := false;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
constructor TDelphiBlockFinishingInfo.Create( pPostScript : AnsiString;
|
||||
pGenSwitch : boolean;
|
||||
pGenAnIf : boolean;
|
||||
pNeedEC : boolean);
|
||||
begin
|
||||
PostScript := pPostScript;
|
||||
GeneratedSwitch := pGenSwitch;
|
||||
GeneratedAnIf := pGenAnIf;
|
||||
NeedAnErrorClause := pNeedEC;
|
||||
NeedAClosingEnd := false;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,82 @@
|
||||
unit dpglib.DelphiCharFormatter;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
dpglib.types;
|
||||
|
||||
type
|
||||
TDelphiCharFormatter = class( TInterfacedObject, ICharFormatter)
|
||||
// ----------------------------------------------------------------------
|
||||
// IdpgCharFormatter methods
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
function EscapeChar( pChar : integer;
|
||||
pForCharLiteral : boolean) : AnsiString;
|
||||
function EscapeString( pString : AnsiString) : AnsiString;
|
||||
function LiteralChar( pChar : integer) : AnsiString;
|
||||
function LiteralString( pString : AnsiString) : AnsiString;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TDelphiCharFormatter }
|
||||
|
||||
// @@@: IdpgCharFormatter +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IdpgCharFormatter
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// EscapeChar
|
||||
//
|
||||
// Given a character value, return a string representing the character that can be embedded
|
||||
// inside a string literal or character literal.
|
||||
// ================================================================================================
|
||||
function TDelphiCharFormatter.EscapeChar( pChar : integer;
|
||||
pForCharLiteral: boolean): AnsiString;
|
||||
begin
|
||||
result := AnsiChar(pChar);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// EscapeString
|
||||
//
|
||||
// Converts a string into a representation that can be uses as a literal when surrounded by
|
||||
// quotes.
|
||||
// ================================================================================================
|
||||
function TDelphiCharFormatter.EscapeString(pString: AnsiString): AnsiString;
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
result := '';
|
||||
|
||||
for i:=1 to Length(pString) do
|
||||
result := result + EscapeChar( ord(pString[i]), false);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// LiteralChar
|
||||
//
|
||||
// Given a character value, return a string representing a character literal that can be
|
||||
// recognized by the target language compiler.
|
||||
// ================================================================================================
|
||||
function TDelphiCharFormatter.LiteralChar(pChar: integer): AnsiString;
|
||||
begin
|
||||
result := '''' + EscapeChar( ord(pChar), true) + '''';
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// LiteralString
|
||||
// ================================================================================================
|
||||
function TDelphiCharFormatter.LiteralString(pString: AnsiString): AnsiString;
|
||||
begin
|
||||
result := '''' + EscapeString( pString) + '''';
|
||||
end;
|
||||
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,77 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.dpgLexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.DpgLexerTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_TREE_BEGIN = 46;
|
||||
LT_finally = 21;
|
||||
TT_QUEST = 34;
|
||||
TT_INT_RULEREF = 54;
|
||||
TT_IMPLIES = 33;
|
||||
LT_returns = 18;
|
||||
TT_WILDCARD = 41;
|
||||
TT_OR = 39;
|
||||
TT_CLOSE = 44;
|
||||
TT_WS = 63;
|
||||
LT_public = 17;
|
||||
TT_RCURLY = 28;
|
||||
TT_COMMA = 31;
|
||||
LT_parser = 9;
|
||||
LT_unit = 4;
|
||||
TT_CHARLIT = 47;
|
||||
LT_tokens = 12;
|
||||
LT_uses = 5;
|
||||
TT_SEMI = 30;
|
||||
TT_ASSIGN = 32;
|
||||
TT_OPEN = 43;
|
||||
LT_treeparser = 10;
|
||||
LT_memberdecl = 13;
|
||||
TT_OPTIONS = 24;
|
||||
TT_AT = 37;
|
||||
LT_local = 19;
|
||||
TT_SEMPRED = 22;
|
||||
TT_CARET = 45;
|
||||
TT_MLCOMMENT2 = 58;
|
||||
TT_DDIGIT = 61;
|
||||
LT_lexer = 8;
|
||||
LT_memberdef = 14;
|
||||
TT_RULEREF = 53;
|
||||
LT_except = 20;
|
||||
TT_COLON = 29;
|
||||
TT_EOF = 1;
|
||||
LT_protected = 16;
|
||||
TT_INTEGER = 49;
|
||||
TT_STAR = 36;
|
||||
TT_ACTION = 51;
|
||||
LT_type = 7;
|
||||
LT_private = 15;
|
||||
TT_LPAREN = 26;
|
||||
TT_RPAREN = 27;
|
||||
TT_BANG = 40;
|
||||
TT_MLCOMMENT1 = 57;
|
||||
TT_DNUMBER = 59;
|
||||
TT_TOKENS = 25;
|
||||
TT_ESC = 65;
|
||||
TT_USES = 23;
|
||||
TT_TOKENREF = 52;
|
||||
TT_NOT = 38;
|
||||
TT_SLCOMMENT = 56;
|
||||
TT_STRINGLIT = 48;
|
||||
TT_XDIGIT = 62;
|
||||
TT_WS_LOOP = 64;
|
||||
LT_options = 11;
|
||||
LT_const = 6;
|
||||
TT_ARGACTION = 50;
|
||||
TT_RANGE = 42;
|
||||
TT_PLUS = 35;
|
||||
TT_XNUMBER = 60;
|
||||
TT_COMMENT = 55;
|
||||
|
||||
implementation
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,77 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.dpgParser.g
|
||||
// ============================================================================
|
||||
unit dpglib.DpgParserTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_TREE_BEGIN = 46;
|
||||
LT_finally = 21;
|
||||
TT_QUEST = 34;
|
||||
TT_INT_RULEREF = 54;
|
||||
TT_IMPLIES = 33;
|
||||
LT_returns = 18;
|
||||
TT_WILDCARD = 41;
|
||||
TT_OR = 39;
|
||||
TT_CLOSE = 44;
|
||||
TT_WS = 63;
|
||||
LT_public = 17;
|
||||
TT_RCURLY = 28;
|
||||
TT_COMMA = 31;
|
||||
LT_parser = 9;
|
||||
TT_CHARLIT = 47;
|
||||
LT_unit = 4;
|
||||
LT_tokens = 12;
|
||||
LT_uses = 5;
|
||||
TT_SEMI = 30;
|
||||
TT_ASSIGN = 32;
|
||||
TT_OPEN = 43;
|
||||
LT_treeparser = 10;
|
||||
LT_memberdecl = 13;
|
||||
TT_OPTIONS = 24;
|
||||
TT_AT = 37;
|
||||
LT_local = 19;
|
||||
TT_SEMPRED = 22;
|
||||
TT_CARET = 45;
|
||||
TT_MLCOMMENT2 = 58;
|
||||
TT_DDIGIT = 61;
|
||||
LT_lexer = 8;
|
||||
LT_memberdef = 14;
|
||||
TT_RULEREF = 53;
|
||||
LT_except = 20;
|
||||
TT_COLON = 29;
|
||||
TT_EOF = 1;
|
||||
LT_protected = 16;
|
||||
TT_INTEGER = 49;
|
||||
TT_STAR = 36;
|
||||
TT_ACTION = 51;
|
||||
LT_type = 7;
|
||||
LT_private = 15;
|
||||
TT_LPAREN = 26;
|
||||
TT_RPAREN = 27;
|
||||
TT_BANG = 40;
|
||||
TT_MLCOMMENT1 = 57;
|
||||
TT_DNUMBER = 59;
|
||||
TT_TOKENS = 25;
|
||||
TT_ESC = 65;
|
||||
TT_USES = 23;
|
||||
TT_TOKENREF = 52;
|
||||
TT_NOT = 38;
|
||||
TT_SLCOMMENT = 56;
|
||||
TT_STRINGLIT = 48;
|
||||
TT_XDIGIT = 62;
|
||||
TT_WS_LOOP = 64;
|
||||
LT_options = 11;
|
||||
LT_const = 6;
|
||||
TT_ARGACTION = 50;
|
||||
TT_RANGE = 42;
|
||||
TT_PLUS = 35;
|
||||
TT_XNUMBER = 60;
|
||||
TT_COMMENT = 55;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,83 @@
|
||||
unit dpglib.ExceptionHandler;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TExceptionHandler declaration
|
||||
// =========================================================================
|
||||
TExceptionHandler = class( TInterfacedObject,
|
||||
IExceptionHandler)
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fTypeAndName : IToken;
|
||||
fAction : IToken;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pTypeAndName : IToken;
|
||||
pAction : IToken);
|
||||
destructor Destroy; override;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IExceptionHandler methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetTypeAndName : IToken;
|
||||
function GetAction : IToken;
|
||||
end;
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TExceptionHandler.Create( pTypeAndName : IToken;
|
||||
pAction : IToken);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fTypeAndName := pTypeAndName;
|
||||
fAction := pAction;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TExceptionHandler.Destroy;
|
||||
begin
|
||||
fTypeAndName := nil;
|
||||
fAction := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IExceptionHandler implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetTypeAndName
|
||||
// ============================================================================
|
||||
function TExceptionHandler.GetTypeAndName: IToken;
|
||||
begin
|
||||
result := fTypeAndName;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetAction
|
||||
// ============================================================================
|
||||
function TExceptionHandler.GetAction: IToken;
|
||||
begin
|
||||
result := fAction;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,97 @@
|
||||
unit dpglib.ExceptionSpec;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
dpgrtl.types,
|
||||
dpglib.Types;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TExceptionSpec declaration
|
||||
// =========================================================================
|
||||
TExceptionSpec = class( TInterfacedObject,
|
||||
IExceptionSpec)
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fLabel : IToken;
|
||||
fHandlers : TInterfaceList;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pLabel: IToken);
|
||||
destructor Destroy; override;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IExceptionSpec methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetLabel : IToken;
|
||||
function GetHandlers: TInterfaceList;
|
||||
|
||||
public
|
||||
procedure AddHandler( pHandler: IExceptionHandler);
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils;
|
||||
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TExceptionSpec.Create(pLabel: IToken);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fLabel := pLabel;
|
||||
fHandlers := TInterfaceList.Create;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TExceptionSpec.Destroy;
|
||||
begin
|
||||
FreeAndNil( fHandlers);
|
||||
fLabel := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IExceptionSpec implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetLabel
|
||||
// ============================================================================
|
||||
function TExceptionSpec.GetLabel: IToken;
|
||||
begin
|
||||
result := fLabel;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetHandlers
|
||||
// ============================================================================
|
||||
function TExceptionSpec.GetHandlers: TInterfaceList;
|
||||
begin
|
||||
result := fHandlers;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AddHandler
|
||||
// ============================================================================
|
||||
procedure TExceptionSpec.AddHandler(pHandler: IExceptionHandler);
|
||||
begin
|
||||
fHandlers.Add( pHandler);
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,626 @@
|
||||
unit dpglib.Grammar;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.Contnrs,
|
||||
dpgrtl.types,
|
||||
dpglib.Types;
|
||||
|
||||
type
|
||||
TGrammar = class( TInterfacedObject, IGrammar)
|
||||
|
||||
protected
|
||||
fCharVocabulary : TByteSet;
|
||||
fTool : ITool;
|
||||
fGenerator : ICodeGenerator;
|
||||
fAnalyzer : ILLkAnalyzer;
|
||||
fRules : TInterfaceList;
|
||||
fMaxK : integer;
|
||||
fSymbols : TStringList; //???
|
||||
fUses : TStringList;
|
||||
fUses2 : TStringList;
|
||||
|
||||
fConst : IToken;
|
||||
fType : IToken;
|
||||
|
||||
fAnalyzerDebug : boolean;
|
||||
fInteractive : boolean;
|
||||
fHasSynPred : boolean;
|
||||
fHasErrHandling : boolean;
|
||||
|
||||
fFileName : AnsiString;
|
||||
fUnitName : AnsiString;
|
||||
fGrammarName : AnsiString;
|
||||
fSuperName : AnsiString;
|
||||
fGrammarFile : AnsiString;
|
||||
|
||||
fTokenManager : ITokenManager;
|
||||
|
||||
fImportVocab : IToken;
|
||||
fExportVocab : AnsiString;
|
||||
|
||||
fTraceRules : boolean;
|
||||
fDebugOutput : boolean;
|
||||
fDefErrorHandler : boolean;
|
||||
|
||||
fMemberAction : IToken;
|
||||
fMemberDecl : AnsiString;
|
||||
fMemberDef : AnsiString;
|
||||
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ------------------------------------------------------------
|
||||
constructor Create( pObjectName : IToken;
|
||||
pTool : ITool;
|
||||
pSuperName : IToken);
|
||||
destructor Destroy; override;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// IGrammar methods
|
||||
// ------------------------------------------------------------
|
||||
function GetImportVocab : IToken; virtual;
|
||||
function GetExportVocab : AnsiString; virtual;
|
||||
|
||||
procedure SetImportVocab( pVocab : IToken); virtual;
|
||||
procedure SetExportVocab( pVocab : AnsiString); virtual;
|
||||
|
||||
procedure Generate; virtual; abstract;
|
||||
|
||||
function GetFileName : AnsiString;
|
||||
function GetUnitName : AnsiString;
|
||||
function GetObjectName : AnsiString;
|
||||
function GetGrammarName : AnsiString;
|
||||
function GetSuperName : AnsiString;
|
||||
function GetMaxK : integer;
|
||||
function GetTool : ITool;
|
||||
function GetAnalyzer : ILLkAnalyzer;
|
||||
function GetCodeGenerator : ICodeGenerator;
|
||||
function GetTokenManager : ITokenManager;
|
||||
function GetHasSynPred : boolean;
|
||||
function GetMemberAction : IToken;
|
||||
function GetCharVocabulary : TByteSet;
|
||||
function GetRules : TInterfaceList;
|
||||
function GetUsesList : TStringList;
|
||||
function GetUsesList2 : TStringList;
|
||||
|
||||
function GetMemberDecl : AnsiString;
|
||||
function GetMemberDef : AnsiString;
|
||||
|
||||
function GetConstAction : IToken;
|
||||
function GetTypeAction : IToken;
|
||||
function GetGrammarFile : AnsiString;
|
||||
|
||||
function GetDefErrorHandler : boolean;
|
||||
|
||||
// function GetDefined( pID : AnsiString): boolean;
|
||||
function GetSymbol( pRule : AnsiString): ITokenSymbol;
|
||||
|
||||
procedure SetUnitName( pUnit : AnsiString);
|
||||
procedure SetAnalyzer( pAnalyzer : ILLkAnalyzer);
|
||||
procedure SetTokenManager( pTokenManager : ITokenManager);
|
||||
procedure SetDefErrorHandler( pHandler : boolean);
|
||||
procedure SetHasSynPred( pHasSynPred : boolean);
|
||||
procedure SetMemberAction( pAction : IToken);
|
||||
procedure SetCharVocabulary( pVocab : TByteSet);
|
||||
|
||||
procedure SetMemberDecl( pDecl : AnsiString);
|
||||
procedure SetMemberDef( pDef : AnsiString);
|
||||
procedure SetConstAction( pConst : IToken);
|
||||
procedure SetTypeAction( pType : IToken);
|
||||
|
||||
procedure SetCodeGenerator( pGenerator : ICodeGenerator);
|
||||
procedure SetGrammarFile( pFile : AnsiString);
|
||||
|
||||
procedure Define( pSymbol: IRuleSymbol);
|
||||
function SetOption( pOption: IToken; pValue: IToken): boolean; virtual;
|
||||
|
||||
function GetClassName: AnsiString;
|
||||
function Defined( pID: AnsiString): boolean;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils,
|
||||
dpglib.TokenLexer,
|
||||
dpglib.TokenParser,
|
||||
dpglib.TokenManager,
|
||||
dpglib.Messages;
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TGrammar.Create( pObjectName : IToken;
|
||||
pTool : ITool;
|
||||
pSuperName : IToken);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fGrammarName := pObjectName.TokenText;
|
||||
fTool := pTool;
|
||||
|
||||
if pSuperName <> nil then
|
||||
fSuperName := pSuperName.TokenText
|
||||
else
|
||||
fSuperName := '';
|
||||
|
||||
|
||||
fTokenManager := TTokenManager.Create( 'TokenManager', pTool);
|
||||
fRules := TInterfaceList.Create;
|
||||
fSymbols := TStringList.Create;
|
||||
|
||||
fDefErrorHandler := false;
|
||||
fMemberDecl := '';
|
||||
fMemberDef := '';
|
||||
|
||||
fConst := nil;
|
||||
fType := nil;
|
||||
|
||||
fImportVocab := nil;
|
||||
fExportVocab := '';
|
||||
|
||||
fCharVocabulary := [1..255];
|
||||
fMaxK := 1;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Prepare uses list for interface section
|
||||
// ---------------------------------------------------------------
|
||||
fUses := TStringList.Create;
|
||||
fUses.Sorted := true;
|
||||
fUses.Duplicates := dupIgnore;
|
||||
|
||||
fUses.Add( 'Classes' );
|
||||
fUses.Add( 'SysUtils' );
|
||||
fUses.Add( 'dpgrtl.types' );
|
||||
|
||||
if Supports( self, ILexerGrammar) then fUses.Add( 'dpgrtl.lexer') else
|
||||
if Supports( self, IParserGrammar) then fUses.Add( 'dpgrtl.llkparser');
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Prepare uses list for implementation section
|
||||
// ---------------------------------------------------------------
|
||||
fUses2 := TStringList.Create;
|
||||
fUses2.Sorted := true;
|
||||
fUses2.Duplicates := dupIgnore;
|
||||
|
||||
fUses2.Add( 'dpgrtl.exception' );
|
||||
fUses2.Add( 'dpgrtl.token' );
|
||||
|
||||
// if Supports( self, ILexerGrammar) then fUses2.Add( 'dpgrtl.token');
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
// ----------------------------------------------------------------------------
|
||||
destructor TGrammar.Destroy;
|
||||
begin
|
||||
fConst := nil;
|
||||
fType := nil;
|
||||
|
||||
FreeAndNil( fUses);
|
||||
FreeAndNil( fUses2);
|
||||
FreeAndNil( fSymbols);
|
||||
FreeAndNil( fRules);
|
||||
|
||||
fTokenManager := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammar implementation
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// Define
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TGrammar.Define(pSymbol: IRuleSymbol);
|
||||
begin
|
||||
fRules.Add( pSymbol);
|
||||
fSymbols.AddObject( pSymbol.ID, pointer( pSymbol));
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetObjectName
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetObjectName: AnsiString;
|
||||
begin
|
||||
result := fGrammarName;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetSuperName
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetSuperName: AnsiString;
|
||||
begin
|
||||
result := fSuperName;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetMaxK
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetMaxK: integer;
|
||||
begin
|
||||
result := fMaxK;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetAnalyzer
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetAnalyzer: ILLkAnalyzer;
|
||||
begin
|
||||
result := fAnalyzer;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetDefErrorHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetDefErrorHandler: boolean;
|
||||
begin
|
||||
result := fDefErrorHandler;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetFileName
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetFileName: AnsiString;
|
||||
begin
|
||||
result := fFileName;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetSymbol
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetSymbol(pRule: AnsiString): ITokenSymbol;
|
||||
var
|
||||
idx: integer;
|
||||
|
||||
begin
|
||||
idx := fSymbols.IndexOf( prule);
|
||||
|
||||
if idx >= 0 then
|
||||
result := ITokenSymbol( pointer(fSymbols.Objects[idx]))
|
||||
else
|
||||
result := nil;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetDefined
|
||||
// ----------------------------------------------------------------------------
|
||||
//function TGrammar.GetDefined(pID: AnsiString): boolean;
|
||||
//begin
|
||||
//end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetAnalyzer
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TGrammar.SetAnalyzer(pAnalyzer: ILLkAnalyzer);
|
||||
begin
|
||||
fAnalyzer := pAnalyzer;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetTokenManager
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TGrammar.SetTokenManager(pTokenManager: ITokenManager);
|
||||
begin
|
||||
fTokenManager := pTokenManager;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetOption
|
||||
//
|
||||
// Option Value
|
||||
// -------------------------------------------------------
|
||||
// k integer
|
||||
// defaultErrorHandler true/false
|
||||
// ============================================================================
|
||||
function TGrammar.SetOption(pOption, pValue: IToken): boolean;
|
||||
var
|
||||
k: integer;
|
||||
s: AnsiString;
|
||||
begin
|
||||
result := true;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: k
|
||||
// ---------------------------------------------------------------
|
||||
if pOption.TokenText = 'k' then
|
||||
begin
|
||||
k := StrToIntDef( pValue.TokenText, -1);
|
||||
if k < 1 then
|
||||
begin
|
||||
fTool.Error('option "k" must be a positive integer',
|
||||
fGrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn);
|
||||
result := false;
|
||||
end
|
||||
else
|
||||
fMaxK := k;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: defaultErrorHandler
|
||||
// ---------------------------------------------------------------
|
||||
else if pOption.TokenText = 'defaultErrorHandler' then
|
||||
begin
|
||||
if pValue.TokenText = 'true' then
|
||||
fDefErrorHandler := true
|
||||
|
||||
else if pValue.TokenText = 'false' then
|
||||
fDefErrorHandler := false
|
||||
|
||||
else
|
||||
begin
|
||||
fTool.Error('Value for "defaultErrorHandler" must be true or false.',
|
||||
fGrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn);
|
||||
|
||||
result := false;
|
||||
end;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
s := MSG_W_ILLEGALOPTION;
|
||||
|
||||
fTool.Warning( Format( MSG_W_ILLEGALOPTION, [pOption.TokenText]),
|
||||
fGrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn);
|
||||
|
||||
result := false;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TGrammar.GetTool: ITool;
|
||||
begin
|
||||
result := fTool;
|
||||
end;
|
||||
|
||||
function TGrammar.GetCodeGenerator: ICodeGenerator;
|
||||
begin
|
||||
result := fGenerator;
|
||||
end;
|
||||
|
||||
function TGrammar.GetTokenManager: ITokenManager;
|
||||
begin
|
||||
result := fTokenManager;
|
||||
end;
|
||||
|
||||
function TGrammar.GetHasSynPred: boolean;
|
||||
begin
|
||||
result := fHasSynPred;
|
||||
end;
|
||||
|
||||
function TGrammar.GetMemberAction: IToken;
|
||||
begin
|
||||
result := fMemberAction;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetDefErrorHandler(pHandler: boolean);
|
||||
begin
|
||||
fDefErrorHandler := fDefErrorHandler;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetHasSynPred(pHasSynPred: boolean);
|
||||
begin
|
||||
fHasSynPred := pHasSynPred;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetMemberAction(pAction: IToken);
|
||||
begin
|
||||
fMemberAction := pAction;
|
||||
end;
|
||||
|
||||
function TGrammar.GetClassName: AnsiString;
|
||||
begin
|
||||
result := fGrammarName;
|
||||
end;
|
||||
|
||||
function TGrammar.Defined(pID: AnsiString): boolean;
|
||||
begin
|
||||
if fSymbols.IndexOf( pID) >= 0 then
|
||||
result := true
|
||||
else
|
||||
result := false;
|
||||
end;
|
||||
|
||||
function TGrammar.GetCharVocabulary: TByteSet;
|
||||
begin
|
||||
result := fCharVocabulary;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetCharVocabulary(pVocab: TByteSet);
|
||||
begin
|
||||
fCharVocabulary := pVocab;
|
||||
end;
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// GetUnitName
|
||||
// ============================================================================
|
||||
function TGrammar.GetUnitName: AnsiString;
|
||||
begin
|
||||
result := fUnitName;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetUnitName
|
||||
// ============================================================================
|
||||
procedure TGrammar.SetUnitName(pUnit: AnsiString);
|
||||
begin
|
||||
fUnitName := pUnit;
|
||||
fFileName := pUnit + '.pas';
|
||||
// fExportVocab := pUnit;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetGrammarName: AnsiString;
|
||||
begin
|
||||
result := fGrammarName;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetRules: TInterfaceList;
|
||||
begin
|
||||
result := fRules;
|
||||
end;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetUsesList
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammar.GetUsesList: TStringList;
|
||||
begin
|
||||
result := fUses;
|
||||
end;
|
||||
|
||||
function TGrammar.GetUsesList2: TStringList;
|
||||
begin
|
||||
result := fUses2;
|
||||
end;
|
||||
|
||||
|
||||
function TGrammar.GetMemberDecl: AnsiString;
|
||||
begin
|
||||
result := fMemberDecl;
|
||||
end;
|
||||
|
||||
function TGrammar.GetMemberDef: AnsiString;
|
||||
begin
|
||||
result := fMemberDef;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetMemberDecl(pDecl: AnsiString);
|
||||
begin
|
||||
fMemberDecl := pDecl;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetMemberDef(pDef: AnsiString);
|
||||
begin
|
||||
fMemberDef := pDef;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetCodeGenerator(pGenerator: ICodeGenerator);
|
||||
begin
|
||||
fGenerator := pGenerator;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetImportVocab
|
||||
// ============================================================================
|
||||
function TGrammar.GetImportVocab: IToken;
|
||||
begin
|
||||
result := fImportVocab;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetExportVocab
|
||||
// ============================================================================
|
||||
function TGrammar.GetExportVocab: AnsiString;
|
||||
begin
|
||||
result := fExportVocab;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetImportVocab
|
||||
// ============================================================================
|
||||
procedure TGrammar.SetImportVocab(pVocab: IToken);
|
||||
var
|
||||
stream : TFileStream;
|
||||
lexer : ITokenStream;
|
||||
parser : TTokenParser;
|
||||
fname : AnsiString;
|
||||
|
||||
begin
|
||||
if fImportVocab = nil then
|
||||
begin
|
||||
|
||||
|
||||
try
|
||||
fImportVocab := pVocab;
|
||||
fname := pVocab.TokenText + 'Tokens.txt';
|
||||
stream := TFileStream.Create( fName, fmOpenRead);
|
||||
except
|
||||
|
||||
|
||||
fTool.Warning( Format( MSG_W_CANTIMPORT, [fname]),
|
||||
fGrammarFile,
|
||||
pVocab.TokenLine,
|
||||
pVocab.TokenColumn);
|
||||
|
||||
fImportVocab := nil;
|
||||
stream := nil;
|
||||
end;
|
||||
|
||||
|
||||
if stream <> nil then
|
||||
begin
|
||||
lexer := TTokenLexer.Create( stream);
|
||||
parser := TTokenParser.Create(lexer);
|
||||
|
||||
try
|
||||
parser.tokenFile( fTokenManager);
|
||||
except
|
||||
end;
|
||||
|
||||
FreeAndNil( stream);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetExportVocab
|
||||
// ============================================================================
|
||||
procedure TGrammar.SetExportVocab(pVocab: AnsiString);
|
||||
begin
|
||||
fExportVocab := pVocab;
|
||||
end;
|
||||
|
||||
function TGrammar.GetConstAction: IToken;
|
||||
begin
|
||||
result := fConst;
|
||||
end;
|
||||
|
||||
function TGrammar.GetTypeAction: IToken;
|
||||
begin
|
||||
result := fType;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetConstAction(pConst: IToken);
|
||||
begin
|
||||
fConst := pConst;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetTypeAction(pType: IToken);
|
||||
begin
|
||||
fType := pType;
|
||||
end;
|
||||
|
||||
function TGrammar.GetGrammarFile: AnsiString;
|
||||
begin
|
||||
result := fGrammarFile;
|
||||
end;
|
||||
|
||||
procedure TGrammar.SetGrammarFile(pFile: AnsiString);
|
||||
begin
|
||||
fGrammarFile := pFile;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,176 @@
|
||||
unit dpglib.GrammarAtom;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.AlternativeElem;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TGrammarAtom declaration
|
||||
// =========================================================================
|
||||
TGrammarAtom = class( TAlternativeElem,
|
||||
IGrammarAtom,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// Members
|
||||
// ------------------------------------------------------------
|
||||
fLabel : AnsiString;
|
||||
fAtomText : AnsiString;
|
||||
fTokenType : integer;
|
||||
fNot : boolean;
|
||||
fASTNodeType : AnsiString;
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ------------------------------------------------------------
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pAutoGenType: integer);
|
||||
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// IGrammarElem methods
|
||||
// ------------------------------------------------------------
|
||||
function AsString : AnsiString;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// IAlternativeElem methods
|
||||
// ------------------------------------------------------------
|
||||
function GetLabel : AnsiString;
|
||||
procedure SetLabel(pLabel: AnsiString);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// IGrammarAtom methods
|
||||
// ------------------------------------------------------------
|
||||
function GetAtomText : AnsiString;
|
||||
function GetASTNodeType: AnsiString;
|
||||
function GetTokenType : integer;
|
||||
function GetIsNot : boolean;
|
||||
|
||||
procedure SetASTNodeType( pASTNodeType : AnsiString);
|
||||
|
||||
procedure SetOption( pKey: IToken; pValue: IToken);
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpglib.GrammarElem;
|
||||
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
constructor TGrammarAtom.Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pAutoGenType: integer);
|
||||
begin
|
||||
inherited Create( pGrammar, pToken, pAutoGenType);
|
||||
|
||||
fAtomText := pToken.TokenText;
|
||||
fTokenType := TT_INVALID;
|
||||
fNot := false;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem implementation
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// ToString
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammarAtom.AsString: AnsiString;
|
||||
begin
|
||||
result := '';
|
||||
if fLabel <> '' then result := result + fLabel + ':';
|
||||
if fNot = true then result := result + '~';
|
||||
|
||||
result := result + fAtomtext;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IAlternativeElem implementation
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetLabel
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammarAtom.GetLabel: AnsiString;
|
||||
begin
|
||||
result := fLabel;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetLabel
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TGrammarAtom.SetLabel(pLabel: AnsiString);
|
||||
begin
|
||||
fLabel := pLabel;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarAtom implementation
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetText
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammarAtom.GetAtomText: AnsiString;
|
||||
begin
|
||||
result := fAtomText;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetType
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammarAtom.GetTokenType: integer;
|
||||
begin
|
||||
result := fTokenType;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetIsNot
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammarAtom.GetIsNot: boolean;
|
||||
begin
|
||||
result := fNot;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetASTNodeType;
|
||||
// ----------------------------------------------------------------------------
|
||||
function TGrammarAtom.GetASTNodeType: AnsiString;
|
||||
begin
|
||||
result := fASTNodeType;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetASTNodeType
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TGrammarAtom.SetASTNodeType(pASTNodeType: AnsiString);
|
||||
begin
|
||||
fASTNodeType := pASTNodeType;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetOption
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TGrammarAtom.SetOption(pKey: IToken; pValue: IToken);
|
||||
begin
|
||||
if pKey.TokenText = 'AST' then
|
||||
SetASTNodeType( pValue.TokenText)
|
||||
|
||||
else
|
||||
fGrammar.Tool.Error( 'Invalid element option: ' + String(pKey.TokenText),
|
||||
fGrammar.GrammarFile,
|
||||
pKey.TokenLine,
|
||||
pKey.TokenColumn);
|
||||
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,950 @@
|
||||
unit dpglib.GrammarBehavior;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
dpgrtl.types,
|
||||
dpglib.Types;
|
||||
|
||||
type
|
||||
TGrammarBehavior = class( TInterfacedObject, IGrammarBehavior)
|
||||
protected
|
||||
fGrammar : IGrammar;
|
||||
fTool : ITool;
|
||||
fAnalyzer : ILLkAnalyzer;
|
||||
fUsesList : TStringList;
|
||||
|
||||
fIsLexer : boolean;
|
||||
fIsParser : boolean;
|
||||
fIsTreeWalker : boolean;
|
||||
|
||||
fLexerGrammar : ILexerGrammar;
|
||||
fParserGrammar : IParserGrammar;
|
||||
fTreeWalkerGrammar: ITreeWalkerGrammar;
|
||||
|
||||
fLanguage : AnsiString;
|
||||
fExchangeDir : AnsiString;
|
||||
|
||||
fConstAction : IToken;
|
||||
fTypeAction : IToken;
|
||||
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// _RefRule
|
||||
// ------------------------------------------------------------
|
||||
procedure _RefStringLiteral( pLiteral : IToken);
|
||||
procedure _RefToken( pToken : IToken);
|
||||
procedure _RefRule( pRuleName : IToken);
|
||||
|
||||
public
|
||||
constructor Create( pTool : ITool;
|
||||
pAnalyzer : ILLkAnalyzer;
|
||||
pExchangeDir : AnsiString);
|
||||
destructor Destroy; override;
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// IGrammarBehavior methods
|
||||
// ------------------------------------------------------------
|
||||
function Grammar: IGrammar;
|
||||
|
||||
procedure AbortGrammar; virtual;
|
||||
|
||||
procedure BeginAlt( pDoAST: boolean); virtual; abstract;
|
||||
procedure BeginExceptionGroup; virtual; abstract;
|
||||
procedure BeginExceptionSpec( pLabel : IToken); virtual; abstract;
|
||||
|
||||
procedure BeginSubRule( pLabel : IToken;
|
||||
pStart : IToken;
|
||||
pNot : boolean); virtual; abstract;
|
||||
|
||||
procedure BeginTree( pStart : IToken); virtual; abstract;
|
||||
procedure BeginChildList; virtual; abstract;
|
||||
|
||||
|
||||
|
||||
procedure DefineGrammarUnit( pUnit : AnsiString); virtual;
|
||||
procedure DefineRuleName( pRule : IToken;
|
||||
pAccess : AnsiString;
|
||||
pRuleAutoGen : boolean;
|
||||
pDocComment : AnsiString); virtual;
|
||||
|
||||
procedure DefineToken( pTokenName : IToken;
|
||||
pTokenLiteral : IToken); virtual;
|
||||
|
||||
procedure DefineUses( pUses : AnsiString); virtual;
|
||||
|
||||
procedure EndAlt; virtual; abstract;
|
||||
procedure EndExceptionGroup; virtual; abstract;
|
||||
procedure EndExceptionSpec; virtual; abstract;
|
||||
procedure EndGrammar; virtual; abstract;
|
||||
procedure EndOptions; virtual;
|
||||
procedure EndRule( pRuleName : AnsiString); virtual; abstract;
|
||||
procedure EndSubRule; virtual; abstract;
|
||||
procedure EndTree; virtual; abstract;
|
||||
procedure EndChildList; virtual; abstract;
|
||||
|
||||
procedure HasError; virtual; abstract;
|
||||
|
||||
procedure NoASTSubRule; virtual; abstract;
|
||||
procedure OneOrMoreSubRule; virtual; abstract;
|
||||
procedure NMSubRule; virtual; abstract;
|
||||
procedure OptionalSubRule; virtual; abstract;
|
||||
|
||||
procedure refRangeLow( M : integer); virtual; abstract;
|
||||
procedure refRangeHigh( N : integer); virtual; abstract;
|
||||
|
||||
procedure RefAction( pAction : IToken); virtual; abstract;
|
||||
procedure RefArgAction( pAction : IToken); virtual; abstract;
|
||||
|
||||
procedure RefCharLiteral( pLiteral : IToken;
|
||||
pLabel : IToken;
|
||||
pInverted : boolean;
|
||||
pAutoGenType : integer;
|
||||
pLastInRule : boolean); virtual; abstract;
|
||||
|
||||
procedure RefCharRange( pToken1 : IToken;
|
||||
pToken2 : IToken;
|
||||
pLabel : IToken;
|
||||
pAutoGenType : integer;
|
||||
pLastInRule : boolean); virtual; abstract;
|
||||
|
||||
procedure RefConstAction( pConstAction : IToken); virtual;
|
||||
procedure RefTypeAction( pTypeAction : IToken); virtual;
|
||||
|
||||
|
||||
procedure RefElemOption( pOption : IToken;
|
||||
pValue : IToken); virtual; abstract;
|
||||
|
||||
procedure RefTokenSpecElemOption( pToken : IToken;
|
||||
pOption : IToken;
|
||||
pValue : IToken); virtual; abstract;
|
||||
|
||||
procedure RefExceptionHandler( pTypeAndName : IToken;
|
||||
pAction : IToken); virtual; abstract;
|
||||
|
||||
procedure RefInitAction( pAction : IToken); virtual; abstract;
|
||||
procedure RefMemberDecl( pDecl : IToken); virtual;
|
||||
procedure RefMemberDef( pDef : IToken); virtual;
|
||||
procedure RefReturnAction( pAction : IToken); virtual; abstract;
|
||||
|
||||
procedure RefRule( pAssignId : IToken;
|
||||
pRuleName : IToken;
|
||||
pLabel : IToken;
|
||||
pArguments : IToken;
|
||||
pAutoGenType : integer); virtual;
|
||||
|
||||
procedure RefRuleExHandler( pExHandlerType : IToken;
|
||||
pExHandlerCode : IToken); virtual; abstract;
|
||||
procedure RefAltExHandler( pExHandlerType : IToken;
|
||||
pExHandlerCode : IToken); virtual; abstract;
|
||||
|
||||
procedure RefRuleLocals( pLocals : IToken); virtual; abstract;
|
||||
procedure RefSemPred( pSemPred : IToken); virtual; abstract;
|
||||
|
||||
procedure RefStringLiteral( pLiteral : IToken;
|
||||
pLabel : IToken;
|
||||
pAutoGenType : integer;
|
||||
pLastInRule : boolean); virtual;
|
||||
|
||||
procedure RefToken( pAssignId : IToken;
|
||||
pToken : IToken;
|
||||
pLabel : IToken;
|
||||
pArguments : IToken;
|
||||
pInverted : boolean;
|
||||
pAutoGenType : integer;
|
||||
pLAstInRule : boolean); virtual;
|
||||
|
||||
procedure RefTokenRange( pToken1 : IToken;
|
||||
pToken2 : IToken;
|
||||
pLabel : IToken;
|
||||
pAutoGenType : integer;
|
||||
pLastInRule : boolean); virtual;
|
||||
|
||||
|
||||
procedure RefWildCard( pToken : IToken;
|
||||
pLabel : IToken;
|
||||
pAutoGenType : integer); virtual; abstract;
|
||||
|
||||
|
||||
procedure Reset; virtual;
|
||||
|
||||
procedure SetArgOfRuleRef( pArguments : IToken); virtual; abstract;
|
||||
procedure SetCharVocabulary( pVocabulary : TByteSet);virtual;
|
||||
|
||||
procedure setFileOption( poption : IToken;
|
||||
pValue : IToken;
|
||||
pFileName : AnsiString); virtual;
|
||||
|
||||
procedure SetGrammarOption( pOption : IToken;
|
||||
pValue : IToken); virtual;
|
||||
|
||||
procedure setRuleOption( pOption : IToken;
|
||||
pValue : IToken); virtual; abstract;
|
||||
|
||||
procedure SetSubRuleOption( pOption : IToken;
|
||||
pValue : IToken); virtual; abstract;
|
||||
|
||||
procedure SetUserExceptions( pException : AnsiString); virtual; abstract;
|
||||
|
||||
procedure StartLexer( pFileName : AnsiString;
|
||||
pLexerName : IToken;
|
||||
pSuperClass : IToken);
|
||||
|
||||
procedure StartParser( pFileName : AnsiString;
|
||||
pParserName : IToken;
|
||||
pSuperClass : IToken);
|
||||
|
||||
|
||||
procedure StartTreeWalker( pFileName : AnsiString;
|
||||
pParserName : IToken;
|
||||
pSuperClass : IToken);
|
||||
|
||||
procedure SynPred; virtual; abstract;
|
||||
procedure ZeroOrMoreSubRule; virtual; abstract;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils,
|
||||
dpglib.Utils,
|
||||
dpglib.Messages,
|
||||
dpglib.DpgParserTokens,
|
||||
dpglib.TokenSymbol,
|
||||
dpglib.StringSymbol,
|
||||
dpglib.RuleSymbol,
|
||||
dpglib.LexerGrammar,
|
||||
dpglib.ParserGrammar,
|
||||
dpglib.TreeParserGrammar,
|
||||
dpglib.CodeGenerator;
|
||||
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
constructor TGrammarBehavior.Create(pTool : ITool;
|
||||
pAnalyzer : ILLkAnalyzer;
|
||||
pExchangeDir: AnsiString);
|
||||
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fTool := pTool;
|
||||
fAnalyzer := pAnalyzer;
|
||||
|
||||
fLexerGrammar := nil;
|
||||
fParserGrammar := nil;
|
||||
fTreeWalkerGrammar:= nil;
|
||||
|
||||
fIsLexer := false;
|
||||
fIsParser := false;
|
||||
fIsTreeWalker := false;
|
||||
|
||||
fConstAction := nil;
|
||||
fTypeAction := nil;
|
||||
|
||||
fLanguage := 'Delphi';
|
||||
fExchangeDir := pExchangeDir;
|
||||
|
||||
if fExchangeDir <> '' then
|
||||
if fExchangeDir[Length(fExchangeDir)] <> '\' then
|
||||
fExchangeDir := fExchangeDir + '\';
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
// ----------------------------------------------------------------------------
|
||||
destructor TGrammarBehavior.Destroy;
|
||||
begin
|
||||
fTool := nil;
|
||||
fAnalyzer := nil;
|
||||
|
||||
fLexerGrammar := nil;
|
||||
fParserGrammar := nil;
|
||||
fTreeWalkerGrammar:= nil;
|
||||
|
||||
fIsLexer := false;
|
||||
fIsParser := false;
|
||||
fIsTreeWalker := false;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// @@@: IGrammarBehavior implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IGrammarBehavior implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// DefineGrammarUnit
|
||||
// ================================================================================================
|
||||
procedure TGrammarBehavior.DefineGrammarUnit(pUnit: AnsiString);
|
||||
begin
|
||||
fGrammar.UnitName := pUnit;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// DefineRuleName
|
||||
// ================================================================================================
|
||||
procedure TGrammarBehavior.DefineRuleName( pRule : IToken;
|
||||
pAccess : AnsiString;
|
||||
pRuleAutoGen: boolean;
|
||||
pDocComment : AnsiString);
|
||||
var
|
||||
id: AnsiString;
|
||||
ts: ITokenSymbol;
|
||||
rs: IRuleSymbol;
|
||||
|
||||
begin
|
||||
id := pRule.TokenText;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Handle lexer rule definition. Lexer rule name must be TOKENREF,
|
||||
// what means: must begin with capital letter.
|
||||
// ---------------------------------------------------------------
|
||||
if( pRule.TokenType = TT_TOKENREF) then
|
||||
begin
|
||||
// ------------------------------------------------------------
|
||||
// construct valid name for it...
|
||||
// ------------------------------------------------------------
|
||||
id := TCodeGenerator.encodeLexerRuleName( id);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// If this token not defined in TokenManager, define it. This
|
||||
// happens when the rule definition is before any reference to
|
||||
// this rule.
|
||||
// ------------------------------------------------------------
|
||||
if not fGrammar.TokenManager.TokenDefined[ pRule.TokenText] then
|
||||
begin
|
||||
ts := TTokenSymbol.Create( pRule.TokenText);
|
||||
ts.TokenType:= fGrammar.TokenManager.NextTokenType;
|
||||
|
||||
fGrammar.TokenManager.Define( ts);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Check if the rule is already defined in the grammar. If so,
|
||||
// show an error message. In this case the generated code is not
|
||||
// usable....
|
||||
// ---------------------------------------------------------------
|
||||
if fGrammar.Defined( id) then
|
||||
begin
|
||||
fGrammar.Symbol[id].QueryInterface(IRuleSymbol,rs);
|
||||
|
||||
if rs.Defined then
|
||||
begin
|
||||
fTool.Error( Format( MSG_E_RULEREDEF,[ id]),
|
||||
fGrammar.GrammarFile,
|
||||
pRule.TokenLine,
|
||||
pRule.TokenColumn);
|
||||
end;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// ... else the grammar isn't defined, so define it.
|
||||
// ---------------------------------------------------------------
|
||||
else
|
||||
begin
|
||||
rs := TRuleSymbol.Create( id);
|
||||
fGrammar.Define( rs);
|
||||
end;
|
||||
|
||||
rs.Defined := true;
|
||||
rs.Access := pAccess;
|
||||
rs.Comment := pDocComment;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// DefineToken
|
||||
//
|
||||
// Define a token from tokens {...}.
|
||||
// Must be label and literal or just label or just a literal.
|
||||
// ================================================================================================
|
||||
procedure TGrammarBehavior.DefineToken( pTokenName : IToken;
|
||||
pTokenLiteral : IToken);
|
||||
var
|
||||
i : integer;
|
||||
name : AnsiString;
|
||||
literal : AnsiString;
|
||||
ss : IStringSymbol;
|
||||
sx : IStringSymbol;
|
||||
ts : ITokenSymbol;
|
||||
|
||||
begin
|
||||
name := '';
|
||||
literal := '';
|
||||
|
||||
if pTokenName <> nil then name := pTokenName.TokenText;
|
||||
if pTokenLiteral <> nil then literal := pTokenLiteral.TokenText;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// The literal must be a string of printable characters surrounded
|
||||
// by '"'s. See: dpglib.utils.
|
||||
// ---------------------------------------------------------------
|
||||
if literal <> '' then
|
||||
begin
|
||||
for i:=2 to Length(literal) -1 do
|
||||
begin
|
||||
if not IsPrint( literal[i]) then
|
||||
begin
|
||||
fTool.Error( Format( MSG_E_INVSTRINGLITERAL,[ literal]),
|
||||
fGrammar.GrammarFile,
|
||||
pTokenLiteral.TokenLine,
|
||||
pTokenLiteral.TokenColumn);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// OK the literal passed the test, so go...
|
||||
// ---------------------------------------------------------------
|
||||
if literal <> '' then
|
||||
begin
|
||||
ss := nil;
|
||||
ts := fGrammar.TokenManager.TokenSymbol[ literal];
|
||||
|
||||
if ts <> nil then
|
||||
ts.QueryInterface( IStringSymbol,ss);
|
||||
|
||||
if ss <> nil then
|
||||
begin
|
||||
// ---------------------------------------------------------
|
||||
// This literal is known already.
|
||||
// If the literal has no label already, but we can provide
|
||||
// one here, then no problem, just map the label to the literal
|
||||
// and don't change anything else.
|
||||
// Otherwise, labels conflict: error.
|
||||
// ---------------------------------------------------------
|
||||
if (name = '') or (ss.Lbl <> '') then
|
||||
begin
|
||||
fTool.Warning( Format( MSG_W_TOKENSREDEF,[ literal]),
|
||||
fGrammar.GrammarFile,
|
||||
pTokenLiteral.TokenLine,
|
||||
pTokenLiteral.TokenColumn);
|
||||
exit;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// The literal had no label, but new def does. Set it.
|
||||
// ---------------------------------------------------------
|
||||
else if name <> '' then
|
||||
begin
|
||||
ss.Lbl := name;
|
||||
fGrammar.TokenManager.MapToTokenSymbol( name, ss);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// if they provide a name/label and that name/label already
|
||||
// exists, just hook this literal onto old token.
|
||||
// ------------------------------------------------------------
|
||||
if name <> '' then
|
||||
begin
|
||||
ts := fGrammar.TokenManager.TokenSymbol[ name];
|
||||
|
||||
if ts <> nil then
|
||||
begin
|
||||
// ------------------------------------------------------
|
||||
// Watch out that the label is not more than just a token.
|
||||
// If it already has a literal attached, then: conflict.
|
||||
// ------------------------------------------------------
|
||||
if ts.QueryInterface( IStringSymbol, sx) = S_OK then
|
||||
begin
|
||||
fTool.Warning( Format( MSG_W_TOKENSREDEF,[ name]),
|
||||
fGrammar.GrammarFile,
|
||||
pTokenName.TokenLine,
|
||||
pTokenName.TokenColumn);
|
||||
exit;
|
||||
end;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// A simple token symbol such as DECL is defined must
|
||||
// convert it to a AnsiStringLiteralSymbol with a label by
|
||||
// co-opting token type and killing old TokenSymbol.
|
||||
// Kill mapping and entry in vector of token manager.
|
||||
// ------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Now create AnsiString literal with label.
|
||||
// ------------------------------------------------------
|
||||
ss := TStringSymbol.Create( literal);
|
||||
ss.TokenType := ts.TokenType;
|
||||
ss.Lbl := name;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Redefine this critter as a AnsiString literal.
|
||||
// ------------------------------------------------------
|
||||
fGrammar.TokenManager.Define( ss);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Make sure the label can be used also.
|
||||
// ------------------------------------------------------
|
||||
fGrammar.TokenManager.MapToTokenSymbol( name, ss);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Here, literal was labeled but not by a known token symbol.
|
||||
// ------------------------------------------------------------
|
||||
ss := TStringSymbol.Create( literal);
|
||||
ss.TokenType:= fGrammar.TokenManager.NextTokenType;
|
||||
ss.Lbl := name;
|
||||
|
||||
fGrammar.TokenManager.Define(ss);
|
||||
|
||||
if name <> '' then
|
||||
fGrammar.TokenManager.MapToTokenSymbol( name, ss);
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Create a token in the token manager not a literal.
|
||||
// ---------------------------------------------------------------
|
||||
else
|
||||
begin
|
||||
if fGrammar.TokenManager.TokenDefined[ name] then
|
||||
begin
|
||||
fTool.Warning( Format( MSG_W_TOKENSREDEF,[ name]),
|
||||
fGrammar.GrammarFile,
|
||||
pTokenName.TokenLine,
|
||||
pTokenname.TokenColumn);
|
||||
exit;
|
||||
end;
|
||||
|
||||
ts := TTokenSymbol.Create( name);
|
||||
ts.TokenType:= fGrammar.TokenManager.NextTokenType;
|
||||
|
||||
fGrammar.TokenManager.Define(ts);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// DefineUses
|
||||
// ================================================================================================
|
||||
procedure TGrammarBehavior.DefineUses(pUses: AnsiString);
|
||||
begin
|
||||
fGrammar.UsesList.Add( pUses);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// EndOptions
|
||||
//
|
||||
// Called after the optional options section, to compensate for options that
|
||||
// may not have been set.
|
||||
// This method is bigger than it needs to be, but is much more clear if I
|
||||
// delineate all the cases.
|
||||
// ================================================================================================
|
||||
procedure TGrammarBehavior.EndOptions;
|
||||
begin
|
||||
{ TODO : EndOptions not implemented... }
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// refRule
|
||||
// ================================================================================================
|
||||
procedure TGrammarBehavior.refRule( pAssignId : IToken;
|
||||
pRuleName : IToken;
|
||||
pLabel : IToken;
|
||||
pArguments : IToken;
|
||||
pAutoGenType: integer);
|
||||
begin
|
||||
_refRule( pRuleName);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// RefStringLiteral
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.refStringLiteral( pLiteral : IToken;
|
||||
pLabel : IToken;
|
||||
pAutoGenType : integer;
|
||||
pLastInRule : boolean);
|
||||
begin
|
||||
_refStringLiteral( pLiteral);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// RefToken
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.refToken( pAssignId : IToken;
|
||||
pToken : IToken;
|
||||
pLabel : IToken;
|
||||
pArguments : IToken;
|
||||
pInverted : boolean;
|
||||
pAutoGenType : integer;
|
||||
pLAstInRule : boolean);
|
||||
begin
|
||||
_refToken( pToken);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// RefTokenRange
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.refTokenRange( pToken1 : IToken;
|
||||
pToken2 : IToken;
|
||||
pLabel : IToken;
|
||||
pAutoGenType : integer;
|
||||
pLastInRule : boolean);
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Ensure that the DefineGrammar methods are called;
|
||||
// otherwise a range addes more token refs to the alternative by
|
||||
// calling MakeGrammar.refToken etc...
|
||||
// ---------------------------------------------------------------
|
||||
if pToken1.TokenText[1] = '"' then
|
||||
_refStringLiteral( pToken1)
|
||||
else
|
||||
_RefToken( pToken1);
|
||||
|
||||
if pToken2.TokenText[1] = '"' then
|
||||
_RefStringLiteral( pToken2)
|
||||
else
|
||||
_RefToken( pToken2);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// SetCharVocabulary
|
||||
//
|
||||
// Set the character vocabulary for a lexer.
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.SetCharVocabulary(pVocabulary: TByteSet);
|
||||
begin
|
||||
if fIsLexer then
|
||||
fLexerGrammar.CharVocabulary := pVocabulary;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// SetFileOption
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.SetFileOption( pOption : IToken;
|
||||
pValue : IToken;
|
||||
pFileName: AnsiString);
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Option: language
|
||||
// ---------------------------------------------------------------
|
||||
if pOption.TokenText = 'language' then
|
||||
if pValue.TokenType = TT_STRINGLIT then
|
||||
fLanguage := Copy(pValue.TokenText,2,Length(pValue.TokenText)-2)
|
||||
|
||||
else if pValue.TokenType in [TT_TOKENREF,TT_RULEREF] then
|
||||
fLanguage := pValue.TokenText
|
||||
|
||||
else
|
||||
fTool.Error( 'option "language" must be a AnsiString or identifier',
|
||||
fGrammar.GrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Other option is error
|
||||
// ---------------------------------------------------------------
|
||||
else
|
||||
fTool.Error( 'Invalid file-level option: "' + poption.TokenText + '"',
|
||||
fGrammar.GrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn)
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetGrammarOption
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TGrammarBehavior.SetGrammarOption( pOption : IToken;
|
||||
pValue : IToken);
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Option: exportVocab
|
||||
// ---------------------------------------------------------------
|
||||
if pOption.TokenText = 'exportVocab' then
|
||||
if pValue.TokenType in [TT_TOKENREF,TT_RULEREF] then
|
||||
// fGrammar.ExportVocab := fExchangeDir + pValue.TokenText
|
||||
fGrammar.ExportVocab := pValue.TokenText
|
||||
else
|
||||
fTool.Error( 'option "exportVocab" must be an identifier',
|
||||
fGrammar.GrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: importVocab
|
||||
// ---------------------------------------------------------------
|
||||
else if pOption.TokenText = 'importVocab' then
|
||||
if pValue.TokenType in [TT_TOKENREF,TT_RULEREF] then
|
||||
begin
|
||||
pValue.TokenText := fExchangeDir + pValue.TokenText;
|
||||
fGrammar.ImportVocab := pValue
|
||||
end
|
||||
else
|
||||
fTool.Error( 'option "importVocab" must be an identifier',
|
||||
fGrammar.GrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Other options sent to the grammar
|
||||
// ---------------------------------------------------------------
|
||||
else
|
||||
fGrammar.SetOption( pOption, pValue);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Start Lexer
|
||||
// ================================================================================================
|
||||
procedure TGrammarBehavior.StartLexer( pFileName : AnsiString;
|
||||
pLexerName : IToken;
|
||||
pSuperClass : IToken);
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Create lexer, and initialize it
|
||||
// ---------------------------------------------------------------
|
||||
if fGrammar = nil then
|
||||
begin
|
||||
fLexerGrammar := TLexerGrammar.Create(pLexerName,fTool,pSuperClass);
|
||||
|
||||
fGrammar := fLexerGrammar;
|
||||
fGrammar.LLkAnalyzer := fAnalyzer;
|
||||
fGrammar.GrammarFile := pFileName;
|
||||
|
||||
fAnalyzer.Grammar := fGrammar;
|
||||
fIsLexer := true;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Append uses list...
|
||||
// ------------------------------------------------------------
|
||||
fGrammar.UsesList.AddStrings( fUsesList);
|
||||
|
||||
fGrammar.ConstAction := fConstAction;
|
||||
fGrammar.TypeAction := fTypeAction;
|
||||
end
|
||||
else
|
||||
fTool.Panic('A grammar already started');
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Start Parser
|
||||
// ================================================================================================
|
||||
procedure TGrammarBehavior.StartParser( pFileName : AnsiString;
|
||||
pParserName : IToken;
|
||||
pSuperClass : IToken);
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Create parser, and initialize it
|
||||
// ---------------------------------------------------------------
|
||||
if fGrammar = nil then
|
||||
begin
|
||||
fParserGrammar := TParserGrammar.Create(pParserName,fTool,pSuperClass);
|
||||
|
||||
fGrammar := fParserGrammar;
|
||||
fGrammar.LLkAnalyzer := fAnalyzer;
|
||||
fGrammar.GrammarFile := pFileName;
|
||||
|
||||
fAnalyzer.Grammar := fGrammar;
|
||||
fIsParser := true;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Append uses list...
|
||||
// ------------------------------------------------------------
|
||||
fGrammar.UsesList.AddStrings( fUsesList);
|
||||
|
||||
fGrammar.ConstAction := fConstAction;
|
||||
fGrammar.TypeAction := fTypeAction;
|
||||
end
|
||||
|
||||
else
|
||||
fTool.Panic('A grammar already started');
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Start TreeWalker
|
||||
// ================================================================================================
|
||||
procedure TGrammarBehavior.StartTreeWalker( pFileName : AnsiString;
|
||||
pParserName : IToken;
|
||||
pSuperClass : IToken);
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Create parser, and initialize it
|
||||
// ---------------------------------------------------------------
|
||||
if fGrammar = nil then
|
||||
begin
|
||||
fTreeWalkerGrammar := TTreeParserGrammar.Create( pParserName,fTool,pSuperClass);
|
||||
|
||||
fGrammar := fTreeWalkerGrammar;
|
||||
fGrammar.GrammarFile := pFileName;
|
||||
fGrammar.LLkAnalyzer := fAnalyzer;
|
||||
|
||||
fAnalyzer.Grammar := fGrammar;
|
||||
fIsParser := true;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Append uses list...
|
||||
// ------------------------------------------------------------
|
||||
fGrammar.UsesList.AddStrings( fUsesList);
|
||||
|
||||
fGrammar.ConstAction := fConstAction;
|
||||
fGrammar.TypeAction := fTypeAction;
|
||||
end
|
||||
|
||||
else
|
||||
fTool.Panic('A grammar already started');
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// RefMemberDecl
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.RefMemberDecl(pDecl: IToken);
|
||||
begin
|
||||
if pDecl <> nil then
|
||||
fGrammar.MemberDecl := pDecl.TokenText;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// RefMemberDef
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.RefMemberDef(pDef: IToken);
|
||||
begin
|
||||
if pDef <> nil then
|
||||
fGrammar.MemberDef := pDef.TokenText;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// Grammar
|
||||
// ============================================================================
|
||||
function TGrammarBehavior.Grammar: IGrammar;
|
||||
begin
|
||||
result := fGrammar;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// AbortGrammar
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.AbortGrammar;
|
||||
begin
|
||||
Reset;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// Reset
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.Reset;
|
||||
begin
|
||||
fGrammar := nil;
|
||||
fLexerGrammar := nil;
|
||||
fParserGrammar := nil;
|
||||
fTreeWalkerGrammar:= nil;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// Internals
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// _RefStringLiteral
|
||||
//
|
||||
// AnsiStringLiterals are treated like tokens except by the lexer.
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior._RefStringLiteral( pLiteral: IToken);
|
||||
var
|
||||
ss : IStringSymbol;
|
||||
str: AnsiString;
|
||||
|
||||
begin
|
||||
if not fIsLexer then
|
||||
begin
|
||||
str := pLiteral.TokenText;
|
||||
|
||||
if fGrammar.TokenManager.TokenSymbol[str] = nil then
|
||||
begin
|
||||
// fTool.Warning( 'String literal "' + str + '" not defined.',
|
||||
// fGrammar.GrammarFile,
|
||||
// pLiteral.TokenLine,
|
||||
// pLiteral.TokenColumn);
|
||||
|
||||
// ss := TStringSymbol.Create( str);
|
||||
// ss.TokenType:= fGrammar.TokenManager.NextTokenType;
|
||||
|
||||
// fGrammar.TokenManager.Define( ss);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// _RefToken
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior._RefToken( pToken: IToken);
|
||||
var
|
||||
id: AnsiString;
|
||||
ts: ITokenSymbol;
|
||||
|
||||
begin
|
||||
id := pToken.TokenText;
|
||||
|
||||
if not fGrammar.TokenManager.TokenDefined[ id] then
|
||||
begin
|
||||
// ------------------------------------------------------------
|
||||
// Defining new TOKENREF is only allowed in lexer..
|
||||
// ------------------------------------------------------------
|
||||
if fIsLexer then
|
||||
begin
|
||||
ts := TTokenSymbol.Create( id);
|
||||
ts.TokenType:= fGrammar.TokenManager.NextTokenType;
|
||||
|
||||
fGrammar.TokenManager.Define( ts);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// _refRule
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior._RefRule( pRuleName: IToken);
|
||||
var
|
||||
id: AnsiString;
|
||||
|
||||
begin
|
||||
id := pRuleName.TokenText;
|
||||
|
||||
if pRuleName.TokenType = TT_TOKENREF then
|
||||
id := TCodeGenerator.encodeLexerRuleName( id);
|
||||
|
||||
if not fGrammar.Defined( id) then
|
||||
fGrammar.Define( TRuleSymbol.Create( id));
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// RefConstAction
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.RefConstAction(pConstAction: IToken);
|
||||
begin
|
||||
fConstAction := pConstAction;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// RefTypeAction
|
||||
// ============================================================================
|
||||
procedure TGrammarBehavior.RefTypeAction(pTypeAction: IToken);
|
||||
begin
|
||||
fTypeAction := pTypeAction;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,154 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// A GrammarElement is a generic node in our data structure that holds a
|
||||
// grammar in memory. This data structure can be used for static analysis or
|
||||
// for dynamic analysis (during parsing).
|
||||
// Every node must know which grammar owns it, how to generate code, and how
|
||||
// to do analysis.
|
||||
// ----------------------------------------------------------------------------
|
||||
unit dpglib.GrammarElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types;
|
||||
|
||||
type
|
||||
TGrammarElem = class( TInterfacedObject, IGrammarElem)
|
||||
protected
|
||||
fGrammar : IGrammar;
|
||||
fLine : integer;
|
||||
fColumn : integer;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IGrammarElem methods
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function GetLine : integer;
|
||||
function GetColumn : integer;
|
||||
|
||||
procedure SetLine( Line : integer);
|
||||
procedure SetColumn( Colunm : integer);
|
||||
|
||||
procedure Generate;
|
||||
function AsString: AnsiString;
|
||||
function Look( k: integer): ILookahead;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
constructor Create( Grammar: IGrammar); overload;
|
||||
constructor Create( Grammar: IGrammar; Start: IToken); overload;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TGrammarElem.Create(Grammar: IGrammar);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fGrammar := Grammar;
|
||||
fLine := -1;
|
||||
fColumn := -1;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TGrammarElem.Create(Grammar: IGrammar; Start: IToken);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fGrammar := Grammar;
|
||||
fLine := Start.TokenLine;
|
||||
fColumn := Start.TokenColumn;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Destructor
|
||||
// ================================================================================================
|
||||
destructor TGrammarElem.Destroy;
|
||||
begin
|
||||
fGrammar := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// @@@: IGrammarElem implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IGrammarElem implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Line
|
||||
// ================================================================================================
|
||||
function TGrammarElem.GetLine: integer;
|
||||
begin
|
||||
result := fLine;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Column
|
||||
// ================================================================================================
|
||||
function TGrammarElem.GetColumn: integer;
|
||||
begin
|
||||
result := fColumn;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Line
|
||||
// ================================================================================================
|
||||
procedure TGrammarElem.SetLine(Line: integer);
|
||||
begin
|
||||
fLine := Line
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Column
|
||||
// ================================================================================================
|
||||
procedure TGrammarElem.SetColumn(Colunm: integer);
|
||||
begin
|
||||
fColumn := Colunm
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Generate
|
||||
// ================================================================================================
|
||||
procedure TGrammarElem.Generate;
|
||||
begin
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Look
|
||||
// ================================================================================================
|
||||
function TGrammarElem.Look(k: integer): ILookahead;
|
||||
begin
|
||||
result := nil;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// AsString
|
||||
// ================================================================================================
|
||||
function TGrammarElem.AsString: AnsiString;
|
||||
begin
|
||||
result := ''
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,79 @@
|
||||
unit dpglib.GrammarSymbol;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpglib.types;
|
||||
|
||||
type
|
||||
TGrammarSymbol = class( TInterfacedObject, IGrammarSymbol)
|
||||
protected
|
||||
fID: AnsiString;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IdpgGrammar methods
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function GetID: AnsiString;
|
||||
procedure SetID( pID: AnsiString);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
constructor Create; overload;
|
||||
constructor Create( ID: AnsiString); overload;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TGrammarSymbol.Create;
|
||||
begin
|
||||
fID := '';
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TGrammarSymbol.Create(ID: AnsiString);
|
||||
begin
|
||||
fID := ID;
|
||||
end;
|
||||
|
||||
// @@@: IdpgGrammarSymbol implementation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IdpgGrammarSymbol implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get ID
|
||||
// ================================================================================================
|
||||
function TGrammarSymbol.GetID: AnsiString;
|
||||
begin
|
||||
result := fID;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set ID
|
||||
// ================================================================================================
|
||||
procedure TGrammarSymbol.SetID(pID: AnsiString);
|
||||
begin
|
||||
fID := pID;
|
||||
end;
|
||||
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,221 @@
|
||||
unit dpglib.LexerGrammar;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.Contnrs,
|
||||
dpgrtl.types,
|
||||
dpglib.Types,
|
||||
dpglib.Grammar;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TLexerGrammar
|
||||
// =========================================================================
|
||||
TLexerGrammar = class( TGrammar,
|
||||
IGrammar,
|
||||
ILexerGrammar)
|
||||
protected
|
||||
fTestLiterals : boolean;
|
||||
fCaseSensitive : boolean;
|
||||
fFilterMode : boolean;
|
||||
fFilterRule : AnsiString;
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ------------------------------------------------------------
|
||||
constructor Create( pObjectName : IToken;
|
||||
pTool : ITool;
|
||||
pSuperName : IToken);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// IGrammar overrides
|
||||
// ------------------------------------------------------------
|
||||
function SetOption( pOption : IToken;
|
||||
pValue : IToken): boolean;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// ILexerGrammar methoda
|
||||
// ------------------------------------------------------------
|
||||
function GetTestLiterals : boolean;
|
||||
function GetCaseSensitive : boolean;
|
||||
function GetFilterMode : boolean;
|
||||
function GetFilterRule : AnsiString;
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils,
|
||||
dpglib.DpgLexerTokens,
|
||||
dpglib.Messages;
|
||||
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TLexerGrammar.Create( pObjectName : IToken;
|
||||
pTool : ITool;
|
||||
pSuperName : IToken);
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fTestLiterals := false;
|
||||
fCaseSensitive := true;
|
||||
fFilterMode := false;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Lexer usually has no default handling
|
||||
// ---------------------------------------------------------------
|
||||
fDefErrorHandler := false;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// ILexerGrammar implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetTestLiterals
|
||||
// ============================================================================
|
||||
function TLexerGrammar.GetTestLiterals: boolean;
|
||||
begin
|
||||
result := fTestLiterals;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetCaseSensitive
|
||||
// ============================================================================
|
||||
function TLexerGrammar.GetCaseSensitive: boolean;
|
||||
begin
|
||||
result := fCaseSensitive;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetFilterMode
|
||||
// ============================================================================
|
||||
function TLexerGrammar.GetFilterMode: boolean;
|
||||
begin
|
||||
result := fFilterMode;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetFilterRule
|
||||
// ============================================================================
|
||||
function TLexerGrammar.GetFilterRule: AnsiString;
|
||||
begin
|
||||
result := fFilterRule;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammar overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// SetOption
|
||||
//
|
||||
// Option Value
|
||||
// -------------------------------------------------------
|
||||
// testLiterals true/false
|
||||
// caseSensitive true/false
|
||||
// filter true/false/ID
|
||||
// ============================================================================
|
||||
function TLexerGrammar.SetOption(pOption, pValue: IToken): boolean;
|
||||
begin
|
||||
result := true;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: testLiterals
|
||||
// ---------------------------------------------------------------
|
||||
if pOption.TokenText = 'testLiterals' then
|
||||
begin
|
||||
if pValue.TokenText = 'true' then
|
||||
fTestLiterals := true
|
||||
|
||||
else if pValue.TokenText = 'false' then
|
||||
fTestLiterals := false
|
||||
|
||||
else
|
||||
begin
|
||||
fTool.Error('Value for "testLiterals" must be true or false',
|
||||
fGrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn);
|
||||
|
||||
result := false;
|
||||
end;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: defaultErrorHandler
|
||||
// ---------------------------------------------------------------
|
||||
else if pOption.TokenText = 'defaultErrorHandler' then
|
||||
begin
|
||||
fTool.Warning( 'Option "defaultErrorHandler" is invalid for lexer',
|
||||
fGrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn);
|
||||
result := true;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: caseSensitive
|
||||
// ---------------------------------------------------------------
|
||||
else if pOption.TokenText = 'caseSensitive' then
|
||||
begin
|
||||
if pValue.TokenText = 'true' then
|
||||
fCaseSensitive := true
|
||||
|
||||
else if pValue.TokenText = 'false' then
|
||||
fCaseSensitive := false
|
||||
|
||||
else
|
||||
begin
|
||||
fTool.Error('Value for "caseSensitive" must be true or false',
|
||||
fGrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn);
|
||||
|
||||
result := false;
|
||||
end;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: filter
|
||||
// ---------------------------------------------------------------
|
||||
else if pOption.TokenText = 'filter' then
|
||||
begin
|
||||
if pValue.TokenText = 'true' then
|
||||
begin
|
||||
fFilterMode := true;
|
||||
fFilterRule := '';
|
||||
end
|
||||
|
||||
else if pValue.TokenText = 'false' then
|
||||
begin
|
||||
fFilterMode := false;
|
||||
fFilterRule := '';
|
||||
end
|
||||
|
||||
else if pValue.TokenType in [TT_TOKENREF] then
|
||||
begin
|
||||
fFilterMode := true;
|
||||
fFilterRule := pValue.TokenText;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
fTool.Error('Value for "filter" must be true or false or an identifier.',
|
||||
fGrammarFile,
|
||||
pValue.TokenLine,
|
||||
pValue.TokenColumn);
|
||||
|
||||
result := false;
|
||||
end;
|
||||
end
|
||||
|
||||
else
|
||||
result := inherited SetOption(pOption, pValue);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,373 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// This object holds all information needed to represent the lookahead for any
|
||||
// particular lookahead computation for a single lookahead depth.
|
||||
// Final lookahead information is a simple bit set, but intermediate stages
|
||||
// need computation cycle and FOLLOW information.
|
||||
//
|
||||
// Concerning the "fCycle" variable.
|
||||
// If lookahead is computed for a RuleEnd node, then computation is part of
|
||||
// a FOLLOW cycle for this rule.
|
||||
// If lookahead is computed for a RuleBlock node, the computation is part of
|
||||
// a FIRST cycle to this rule.
|
||||
//
|
||||
// Concerning the "fEpsilon" variable. (epsilonDepth)
|
||||
// This is not the depth relative to the rule reference that epsilon was
|
||||
// encountered. That value is:
|
||||
//
|
||||
// initial_k - epsilonDepth + 1
|
||||
//
|
||||
// Also, lookahead depths past rule ref for local follow are:
|
||||
//
|
||||
// initial_k - (initial_k - epsilonDepth)
|
||||
//
|
||||
// Used for rule references. If we try to compute look(k, ruleref) and there
|
||||
// are fewer than k lookahead terminals before the end of the the rule,
|
||||
// epsilon will be returned (don't want to pass the end of the rule).
|
||||
// We must track when the the lookahead got stuck. For example,
|
||||
//
|
||||
// a : b A B E F G;
|
||||
// b : C ;
|
||||
//
|
||||
// LOOK(5, ref-to(b)) is {<EPSILON>} with depth = 4, which indicates that at
|
||||
// 2 (5-4+1) tokens ahead, end of rule was reached.
|
||||
// Therefore, the token at 4=5-(5-4) past rule ref b must be included in the
|
||||
// set == F.
|
||||
//
|
||||
// The situation is complicated by the fact that a computation may hit the
|
||||
// end of a rule at many different depths. For example,
|
||||
//
|
||||
// a : b A B C ;
|
||||
// b : E F // epsilon depth of 1 relative to initial k=3
|
||||
// | G // epsilon depth of 2
|
||||
// ;
|
||||
//
|
||||
// Here, LOOK(3,ref-to(b)) returns epsilon, but the depths are {1, 2};
|
||||
// i.e., 3-(3-1) and 3-(3-2). Those are the lookahead depths past the rule
|
||||
// ref needed for the local follow.
|
||||
//
|
||||
// This is an empty set unless an epsilon is created.
|
||||
// ----------------------------------------------------------------------------
|
||||
unit dpglib.Lookahead;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types;
|
||||
|
||||
type
|
||||
TLookahead = class( TInterfacedObject, ILookahead)
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// Actual 'bitset' of the lookahead
|
||||
// ------------------------------------------------------------
|
||||
fLaSet : TByteSet;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// What 'k' values were being computed when end of rule hit?
|
||||
// ------------------------------------------------------------
|
||||
fEpsilon : TByteSet;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Does this lookahead depth include Epsilon token type? This
|
||||
// is used to avoid having a bit in the set for Epsilon as it
|
||||
// conflicts with parsing binary files.
|
||||
// ------------------------------------------------------------
|
||||
fHasEpsilon : boolean;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Is this computation part of a computation cycle?
|
||||
// ------------------------------------------------------------
|
||||
fCycle : AnsiString;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// ILookahead
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function GetLaSet : TByteSet;
|
||||
function GetEpsilon : TByteSet;
|
||||
function GetHasEpsilon : boolean;
|
||||
function GetCycle : AnsiString;
|
||||
|
||||
procedure SetLaSet( LaSet : TByteSet);
|
||||
procedure SetEpsilon( Epsilon : TByteSet);
|
||||
procedure SetHasEpsilon( HasEpsilon : boolean);
|
||||
procedure SetCycle( Cycle : AnsiString);
|
||||
|
||||
function Intersection( LA : ILookahead) : ILookahead;
|
||||
|
||||
procedure CombineWith( LA : ILookahead); overload;
|
||||
procedure CombineWith( LA : TByteSet); overload;
|
||||
|
||||
function IsNil : boolean;
|
||||
function Clone : ILookahead;
|
||||
|
||||
function AsString( pTM: ITokenManager=nil) : AnsiString;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
constructor Create; overload;
|
||||
constructor Create( La : ILookahead); overload;
|
||||
constructor Create( LaSet : TByteSet); overload;
|
||||
constructor Create( Int : integer); overload;
|
||||
constructor Create( Cycle : AnsiString); overload;
|
||||
|
||||
end;
|
||||
|
||||
TLookaheadArray = array of ILookahead;
|
||||
|
||||
var
|
||||
nullLookahead : ILookahead;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils,
|
||||
dpglib.utils;
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TLookahead.Create;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fLaSet := [];
|
||||
fEpsilon := [];
|
||||
fHasEpsilon := false;
|
||||
fCycle := '';
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(ILookahead)
|
||||
// ================================================================================================
|
||||
constructor TLookahead.Create( La: ILookahead);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fLaSet := La.LaSet;
|
||||
fEpsilon := La.Epsilon;
|
||||
fHasEpsilon := La.HasEpsilon;
|
||||
fCycle := La.Cycle;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(TByteSet)
|
||||
// ================================================================================================
|
||||
constructor TLookahead.Create( LaSet: TByteSet);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fLaSet := LaSet;
|
||||
fEpsilon := [];
|
||||
fHasEpsilon := false;
|
||||
fCycle := '';
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(integer)
|
||||
// ================================================================================================
|
||||
constructor TLookahead.Create( Int: integer);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fLaSet := [Int];
|
||||
fEpsilon := [];
|
||||
fHasEpsilon := false;
|
||||
fCycle := '';
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(string)
|
||||
// ================================================================================================
|
||||
constructor TLookahead.Create( Cycle: AnsiString);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fLaSet := [];
|
||||
fEpsilon := [];
|
||||
fHasEpsilon := false;
|
||||
fCycle := Cycle;
|
||||
end;
|
||||
|
||||
// @@@: ILookahead implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// ILookahead implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get LaSet
|
||||
// ================================================================================================
|
||||
function TLookahead.GetLaSet: TByteSet;
|
||||
begin
|
||||
result := fLaSet;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Epsilon
|
||||
// ================================================================================================
|
||||
function TLookahead.GetEpsilon: TByteSet;
|
||||
begin
|
||||
result := fEpsilon;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get HasEpsilon
|
||||
// ================================================================================================
|
||||
function TLookahead.GetHasEpsilon: boolean;
|
||||
begin
|
||||
result := fHasEpsilon;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Cycle
|
||||
// ================================================================================================
|
||||
function TLookahead.GetCycle: AnsiString;
|
||||
begin
|
||||
result := fCycle;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set LaSet
|
||||
// ================================================================================================
|
||||
procedure TLookahead.SetLaSet( LaSet: TByteSet);
|
||||
begin
|
||||
fLaSet := LaSet
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Epsilon
|
||||
// ================================================================================================
|
||||
procedure TLookahead.SetEpsilon( Epsilon: TByteSet);
|
||||
begin
|
||||
fEpsilon := Epsilon
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set HasEpsilon
|
||||
// ================================================================================================
|
||||
procedure TLookahead.SetHasEpsilon( HasEpsilon: boolean);
|
||||
begin
|
||||
fHasEpsilon := HasEpsilon
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Cycle
|
||||
// ================================================================================================
|
||||
procedure TLookahead.SetCycle( Cycle: AnsiString);
|
||||
begin
|
||||
fCycle := Cycle
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Intersection
|
||||
//
|
||||
// What is the intersection of two lookahead depths?
|
||||
// Only the Epsilon "bit" and bitset are considered.
|
||||
// ================================================================================================
|
||||
function TLookahead.Intersection( LA: ILookahead) : ILookahead;
|
||||
begin
|
||||
result := TLookahead.Create;
|
||||
result.LaSet := fLaSet * LA.LaSet;
|
||||
|
||||
if fHasEpsilon and LA.HasEpsilon then
|
||||
result.HasEpsilon := true;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// CombineWith(ILookahead)
|
||||
// ================================================================================================
|
||||
procedure TLookahead.CombineWith( LA: ILookahead);
|
||||
begin
|
||||
if fCycle = '' then fCycle := LA.Cycle;
|
||||
|
||||
fHasEpsilon := fHasEpsilon or LA.HasEpsilon;
|
||||
fLaSet := fLaSet + LA.LaSet;
|
||||
fEpsilon := fEpsilon + LA.Epsilon;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// CombineWith(TByteSet)
|
||||
// ================================================================================================
|
||||
procedure TLookahead.CombineWith( LA: TByteSet);
|
||||
begin
|
||||
fLaSet := fLaSet + LA;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// IsNil
|
||||
// ================================================================================================
|
||||
function TLookahead.IsNil: boolean;
|
||||
begin
|
||||
result := (fLaSet = []) and not fHasEpsilon;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clone
|
||||
// ================================================================================================
|
||||
function TLookahead.Clone: ILookahead;
|
||||
begin
|
||||
result := TLookahead.Create( self);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// AsString
|
||||
// ================================================================================================
|
||||
function TLookahead.AsString( pTM: ITokenManager): AnsiString;
|
||||
var
|
||||
depths: AnsiString;
|
||||
i : integer;
|
||||
|
||||
begin
|
||||
if pTM = nil then
|
||||
result := CharSetToStr( fLaSet)
|
||||
else
|
||||
result := TokenSetToStr( fLaSet, pTM);
|
||||
|
||||
if fHasEpsilon = true then
|
||||
result := result + '+ <epsilon>';
|
||||
|
||||
if fCycle <> '' then
|
||||
result := result + '; FOLLOW( ' + fCycle + ')';
|
||||
|
||||
if fEpsilon <> [] then
|
||||
begin
|
||||
depths := '';
|
||||
|
||||
for i:=0 to 255 do
|
||||
begin
|
||||
if (fEpsilon * [i]) <> [] then
|
||||
begin
|
||||
if depths <> '' then
|
||||
depths := depths + ',';
|
||||
|
||||
depths := depths + AnsiString(IntToStr( i));
|
||||
end;
|
||||
end;
|
||||
|
||||
result := result + '; depths=' + depths;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
initialization
|
||||
nullLookahead := TLookahead.Create;
|
||||
nullLookahead.HasEpsilon := true;
|
||||
|
||||
finalization
|
||||
nullLookahead := nil;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,67 @@
|
||||
unit dpglib.Messages;
|
||||
|
||||
interface
|
||||
resourcestring
|
||||
MSG_W_RULEACCEPTSNOARGS = 'Rule "%s" accepts no arguments.';
|
||||
MSG_W_RULEHASNORETURN = 'Rule "%s" has no return value.';
|
||||
MSG_W_RULEHASRETURN = 'Rule "%s" returns a value.';
|
||||
MSG_W_OPTIONALPATH = 'Optional path found in NextToken.';
|
||||
MSG_W_SYNTSUPERFLUOUS = 'Syntactic predicate superfluous for single alternative.';
|
||||
MSG_W_SYNTIGNORED = 'Syntactic predicate ignored for single alternative.';
|
||||
|
||||
MSG_E_RULENOTDEFINED = 'Rule "%s" is not defined.';
|
||||
MSG_E_LEXRULENOTDEFINED = 'Lexer rule "%s" is not defined.';
|
||||
MSG_E_NOFILTERRULE = 'Filter rule "%s" does not exist in this lexer.';
|
||||
|
||||
MSG_W_ILLEGALOPTION = 'Illegal option "%s".';
|
||||
MSG_W_ILLEGALRULEOPTION = 'Illegal rule option "%s".';
|
||||
|
||||
MSG_W_ILLEGALDEMOOPTION = 'Option "%s" is invalid in demo version.';
|
||||
MSG_W_CANTIMPORT = 'Cannot import "%s".';
|
||||
|
||||
// behaviour
|
||||
MSG_W_TOKENSREDEF = 'Redefinition of literal in tokens {...} "%s".';
|
||||
MSG_E_RULEREDEF = 'Redefinition of rule "%s".';
|
||||
|
||||
// grammar maker
|
||||
MSG_E_INVSTRINGLITERAL = 'Invalid string literal %s';
|
||||
MSG_W_LEXPUBLICRETURN = 'Public lexical rules cannot specify return type.';
|
||||
MSG_E_ABORTGRAMMAR = 'Aborting grammar "%s" do to errors.';
|
||||
MSG_E_LEXNOTINLEXER = 'Lexical rule "%s" defined outside of lexer.';
|
||||
MSG_E_LEXCAPITAL = 'Lexical rule names must begin with captal letter. "%s" is not.';
|
||||
MSG_E_NONINVSUBRULE = 'This subrule cannot be inverted.';
|
||||
|
||||
MSG_E_NONINVN2M = '"~" cannot be applied to (...)@ subrule.';
|
||||
MSG_E_NONINVOOM = '"~" cannot be applied to (...)+ subrule.';
|
||||
MSG_E_NONINVZOO = '"~" cannot be applied to (...)? subrule.';
|
||||
MSG_E_NONINVZOM = '"~" cannot be applied to (...)* subrule.';
|
||||
MSG_E_NONINVSYNTPRED = '"~" cannot be applied to syntactic predicate.';
|
||||
|
||||
MSG_E_CHARINPARSER = 'Character literal only valid in lexer.';
|
||||
MSG_E_CHARRANGEINPARSER = 'Character range only valid in lexer.';
|
||||
MSG_E_MALFORMEDRANGE = 'Malformed range.';
|
||||
|
||||
MSG_E_ILLEGALTOKENSOPT = 'Invalid tokens {...} element option: "%s".';
|
||||
MSG_E_NOTOKENSTOKEN = 'Cannot find "%s" in tokens {...}.';
|
||||
MSG_E_ILLEGALELEMOPT = 'Cannot use element option "%s" for this kind of element.';
|
||||
MSG_E_PARSERRULEINLEXER = 'Parser rule "%s"refenced in lexer.';
|
||||
MSG_E_ASTINLEXER = 'AST specification "^" not allowed in lexer.';
|
||||
MSG_E_INVTOKENINLEXER = '~TOKEN is not allowed in lexer.';
|
||||
MSG_E_INVTOKENREFINLEXER= 'Assignment from token reference only allowed in lexer.';
|
||||
MSG_E_INVTOKENPARAMLEXER= 'Token reference arguments only allowed in lexer.';
|
||||
MSG_E_TOKENRANGEINLEXER = 'Token range not allowed in lexer.';
|
||||
|
||||
// analyzer
|
||||
MSG_W_INVNONGREEDY = 'Being nongreedy only makes sense for (...)+ and (...)*';
|
||||
MSG_W_INVEMPTYALT = 'Empty alternative makes no sense in (...)* or (...)+';
|
||||
MSG_E_INFRECURSION = 'Infinite recursion to rule "%s" from rule "%s".';
|
||||
|
||||
// altblock
|
||||
MSG_E_INVRULEINSYNPRED = 'Rule "%s" referenced in (...)=>, but not defined.';
|
||||
|
||||
MSG_E_PROTECTEDFILTER = 'Filter rule "%s" must be protected.';
|
||||
MSG_E_CHARLITINNONLEXER = 'Cannot reference character literals in non-lexer grammar: "%s".';
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,138 @@
|
||||
unit dpglib.NMBlock;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.BlockWithImpliedExitPath;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TOneOrMoreBlock declaration
|
||||
// =========================================================================
|
||||
TNMBlock = class( TBlockWithImpliedExitPath,
|
||||
INMBlock,
|
||||
IBlockWithImpliedExitPath,
|
||||
IAlternativeBlock,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
protected
|
||||
fM : integer;
|
||||
fN : integer;
|
||||
|
||||
public
|
||||
procedure AfterConstruction; override;
|
||||
|
||||
protected
|
||||
function GetLow : integer;
|
||||
function GetHigh : integer;
|
||||
|
||||
procedure SetLow( Value: integer);
|
||||
procedure SetHigh(Value: integer);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// AftgerConstruction
|
||||
// ================================================================================================
|
||||
procedure TNMBlock.AfterConstruction;
|
||||
begin
|
||||
fN := 0;
|
||||
fM := MaxInt;
|
||||
end;
|
||||
|
||||
// @@@: dgpGrammarElem overrides ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// dgpGrammarElem overrides
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Generate
|
||||
// ================================================================================================
|
||||
procedure TNMBlock.Generate;
|
||||
begin
|
||||
|
||||
fGrammar.Generator.Gen( self);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Look
|
||||
// ================================================================================================
|
||||
function TNMBlock.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// ToString
|
||||
// ================================================================================================
|
||||
function TNMBlock.AsString: AnsiString;
|
||||
begin
|
||||
result := inherited AsString + '@';
|
||||
end;
|
||||
|
||||
// @@@: Property handlers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Property handlers
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// GetLow
|
||||
// ================================================================================================
|
||||
function TNMBlock.GetLow : integer;
|
||||
begin
|
||||
result := fN;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// GetHigh
|
||||
// ================================================================================================
|
||||
function TNMBlock.GetHigh : integer;
|
||||
begin
|
||||
result := fM
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// SetLow
|
||||
// ================================================================================================
|
||||
procedure TNMBlock.SetLow( Value: integer);
|
||||
begin
|
||||
fN := Value;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// SetHigh
|
||||
// ================================================================================================
|
||||
procedure TNMBlock.SetHigh(Value: integer);
|
||||
begin
|
||||
fM := Value;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,58 @@
|
||||
unit dpglib.OneOrMoreBlock;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.BlockWithImpliedExitPath;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TOneOrMoreBlock declaration
|
||||
// =========================================================================
|
||||
TOneOrMoreBlock = class( TBlockWithImpliedExitPath,
|
||||
IOneOrMoreBlock,
|
||||
IBlockWithImpliedExitPath,
|
||||
IAlternativeBlock,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
end;
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TOneOrMoreBlock.Generate;
|
||||
begin
|
||||
fGrammar.Generator.Gen( self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TOneOrMoreBlock.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// ToString
|
||||
// ============================================================================
|
||||
function TOneOrMoreBlock.AsString: AnsiString;
|
||||
begin
|
||||
result := inherited AsString + '+';
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,109 @@
|
||||
unit dpglib.ParserGrammar;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.Contnrs,
|
||||
dpgrtl.types,
|
||||
dpglib.Types,
|
||||
dpglib.Grammar;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TParserGrammar
|
||||
// =========================================================================
|
||||
TParserGrammar = class( TGrammar,
|
||||
IGrammar,
|
||||
IParserGrammar)
|
||||
private
|
||||
fBuildAST : boolean;
|
||||
|
||||
protected
|
||||
function GetBuildAST: boolean;
|
||||
procedure SetBuildAST( Value: boolean);
|
||||
|
||||
function SetOption( Option: IToken; Value: IToken): boolean;
|
||||
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ------------------------------------------------------------
|
||||
constructor Create( pObjectName : IToken;
|
||||
pTool : ITool;
|
||||
pSuperName : IToken);
|
||||
end;
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ----------------------------------------------------------------------------
|
||||
constructor TParserGrammar.Create( pObjectName : IToken;
|
||||
pTool : ITool;
|
||||
pSuperName : IToken);
|
||||
begin
|
||||
inherited;
|
||||
fBuildAST := false
|
||||
end;
|
||||
|
||||
// @@@: IGrammar ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IGrammar
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get BuildAST
|
||||
// ================================================================================================
|
||||
function TParserGrammar.GetBuildAST: boolean;
|
||||
begin
|
||||
result := fBuildAST
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set BuildAST
|
||||
// ================================================================================================
|
||||
procedure TParserGrammar.SetBuildAST(Value: boolean);
|
||||
begin
|
||||
fBuildAST := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Option
|
||||
// ================================================================================================
|
||||
function TParserGrammar.SetOption(Option, Value: IToken): boolean;
|
||||
begin
|
||||
result := true;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Option: buildAST
|
||||
// ---------------------------------------------------------------
|
||||
if Option.TokenText = 'buildAST' then
|
||||
begin
|
||||
if Value.TokenText = 'true' then
|
||||
fBuildAST := true
|
||||
|
||||
else if Value.TokenText = 'false' then
|
||||
fBuildAST := false
|
||||
|
||||
else begin
|
||||
fTool.Error('Value for "buildAST" must be true or false.',
|
||||
fGrammarFile,
|
||||
Value.TokenLine,
|
||||
Value.TokenColumn);
|
||||
|
||||
result := false
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
result := inherited SetOption(Option, Value);
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,328 @@
|
||||
unit dpglib.PrettyPrinter;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.SysUtils,
|
||||
dpgrtl.types,
|
||||
dpglib.Utils,
|
||||
dpglib.Types,
|
||||
dpglib.CodeGenerator,
|
||||
dpglib.DelphiCharFormatter,
|
||||
dpglib.DelphiBlockFinishingInfo;
|
||||
|
||||
type
|
||||
TPrettyPrinter = class( TCodeGenerator)
|
||||
|
||||
protected
|
||||
fIsLexer : boolean;
|
||||
fIsParser : boolean;
|
||||
fIsTreeWalker : boolean;
|
||||
|
||||
fLexerGrammar : ILexerGrammar;
|
||||
fParserGrammar : IParserGrammar;
|
||||
fTreeWalkerGrammar: ITreeWalkerGrammar;
|
||||
|
||||
protected
|
||||
procedure genGrammar;
|
||||
procedure genUses;
|
||||
procedure genClassDecl;
|
||||
procedure genClassOptions;
|
||||
procedure genClassTokens;
|
||||
procedure genClassMemberDecl;
|
||||
procedure genClassRules;
|
||||
procedure genClassMemberDef;
|
||||
|
||||
procedure genRuleOptions( blk: IRuleBlock);
|
||||
procedure genRuleLocals( blk: IRuleBlock);
|
||||
procedure genRuleInit( blk: IRuleBlock);
|
||||
procedure genRuleBlock( blk: IRuleBlock);
|
||||
|
||||
|
||||
public
|
||||
destructor Destroy; override;
|
||||
|
||||
public
|
||||
procedure gen( pGrammar: IGrammar);
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TPrettyPrinter.Destroy;
|
||||
begin
|
||||
fLexerGrammar := nil;
|
||||
fParserGrammar := nil;
|
||||
fTreeWalkerGrammar := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// gen
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.gen(pGrammar: IGrammar);
|
||||
begin
|
||||
if pGrammar <> nil then
|
||||
begin
|
||||
fIsLexer := false;
|
||||
fIsParser := false;
|
||||
fIsTreeWalker := false;
|
||||
|
||||
pGrammar.QueryInterface( ILexerGrammar, fLexerGrammar);
|
||||
pGrammar.QueryInterface( IParserGrammar, fParserGrammar);
|
||||
pGrammar.QueryInterface( ITreeWalkerGrammar, fTreeWalkerGrammar);
|
||||
|
||||
if fLexerGrammar <> nil then fIsLexer := true;
|
||||
if fParserGrammar <> nil then fIsParser := true;
|
||||
if fTreeWalkerGrammar <> nil then fIsTreeWalker := true;
|
||||
|
||||
fGrammar := pGrammar;
|
||||
genGrammar;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genGrammar
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genGrammar;
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// Calculate the output file name, and open it.
|
||||
// ---------------------------------------------------------------
|
||||
fFile := fOutDir + fGrammar.UnitName + '.pg';
|
||||
fOutput := TFileStream.Create( fFile, fmCreate);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Generate red tape
|
||||
// ---------------------------------------------------------------
|
||||
println('// ----------------------------------------------------------------------------');
|
||||
println('// This is a generated file. Do not modify it by hand!');
|
||||
println('// ----------------------------------------------------------------------------');
|
||||
println('unit ' + fGrammar.UnitName + ';');
|
||||
println('');
|
||||
|
||||
genUses;
|
||||
genClassDecl;
|
||||
|
||||
fOutput.Free;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genUses
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genUses;
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
if fGrammar.UsesList.Count > 0 then
|
||||
begin
|
||||
println('uses');
|
||||
println('{');
|
||||
INC(fTabs);
|
||||
|
||||
for i:=0 to fGrammar.UsesList.Count -1 do
|
||||
println(fGrammar.UsesList.Strings[i] + ';');
|
||||
|
||||
DEC(fTabs);
|
||||
println('}');
|
||||
println('');
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genClassDecl
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genClassDecl;
|
||||
begin
|
||||
// ---------------------------------------------------------------
|
||||
// print class header
|
||||
// ---------------------------------------------------------------
|
||||
if fIsLexer then print('lexer ');
|
||||
if fIsParser then print('parser ');
|
||||
if fIsTreeWalker then print('treewalker ');
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// print class name
|
||||
// ---------------------------------------------------------------
|
||||
_print( fGrammar.GetClassName);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// print superclass (later)
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Close class header
|
||||
// ---------------------------------------------------------------
|
||||
_println(';');
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Generate the rest
|
||||
// ---------------------------------------------------------------
|
||||
genClassOptions;
|
||||
genClassTokens;
|
||||
genClassMemberDecl;
|
||||
genClassRules;
|
||||
genClassMemberDef;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genClassOptions
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genClassOptions;
|
||||
begin
|
||||
println('options');
|
||||
println('{');
|
||||
println('}');
|
||||
println('');
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genClassTokens
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genClassTokens;
|
||||
begin
|
||||
println('tokens');
|
||||
println('{');
|
||||
println('}');
|
||||
println('');
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genClassMemberDecl
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genClassMemberDecl;
|
||||
begin
|
||||
println('memberdecl');
|
||||
println('{');
|
||||
println('}');
|
||||
println('');
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genClassMemberDef
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genClassMemberDef;
|
||||
begin
|
||||
println('memberdef');
|
||||
println('{');
|
||||
println('}');
|
||||
println('');
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genClassRules
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genClassRules;
|
||||
var
|
||||
i : integer;
|
||||
rs : IRuleSymbol;
|
||||
rb : IRuleBlock;
|
||||
|
||||
begin
|
||||
for i:=0 to fGrammar.Rules.Count -1 do
|
||||
begin
|
||||
rs := fGrammar.Rules[i] as IRuleSymbol;
|
||||
rb := rs.Block;
|
||||
|
||||
if (rb = nil) or (rs.ID = 'mNextToken') then
|
||||
continue;
|
||||
|
||||
println('// ============================================================================');
|
||||
println('// ' + rb.RuleName);
|
||||
println('// ============================================================================');
|
||||
// ------------------------------------------------------------
|
||||
// Print rule scope.
|
||||
// ------------------------------------------------------------
|
||||
if rs.Access = 'public' then print('public ')
|
||||
else if rs.Access = 'protected' then print('protected ')
|
||||
else if rs.Access = 'private' then print('private ')
|
||||
else print(' INVALID SCOPE ');
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Print rule ID.
|
||||
// ------------------------------------------------------------
|
||||
_print( rb.RuleName);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Print rule arguments
|
||||
// ------------------------------------------------------------
|
||||
if rb.Arguments <> '' then
|
||||
_print(' ' + rb.Arguments);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Print rule returns
|
||||
// ------------------------------------------------------------
|
||||
if rb.ReturnAction <> '' then
|
||||
_print(' returns ' + rb.ReturnAction);
|
||||
|
||||
_println(';');
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// print rule things
|
||||
// ------------------------------------------------------------
|
||||
genRuleOptions(rb);
|
||||
genRuleLocals(rb);
|
||||
genRuleInit(rb);
|
||||
|
||||
INC(fTabs);
|
||||
println(':');
|
||||
INC(fTabs);
|
||||
|
||||
genRuleBlock(rb);
|
||||
|
||||
DEC(fTabs);
|
||||
println(';');
|
||||
DEC(fTabs);
|
||||
|
||||
println('');
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genRuleOptions
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genRuleOptions(blk: IRuleBlock);
|
||||
begin
|
||||
println('options');
|
||||
println('{');
|
||||
println('}');
|
||||
println('');
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genRuleLocals
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genRuleLocals(blk: IRuleBlock);
|
||||
begin
|
||||
println('locals');
|
||||
println('{');
|
||||
println('}');
|
||||
println('');
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genRuleInit
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genRuleInit(blk: IRuleBlock);
|
||||
begin
|
||||
println('{');
|
||||
println('}');
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// genRuleBlock
|
||||
// ============================================================================
|
||||
procedure TPrettyPrinter.genRuleBlock(blk: IRuleBlock);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,144 @@
|
||||
unit dpglib.RuleEndElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.Lookahead,
|
||||
dpglib.BlockEndElem;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TRuleEndElem declaration
|
||||
// =========================================================================
|
||||
TRuleEndElem = class( TBlockEndElem,
|
||||
IRuleEndElem,
|
||||
IBlockEndElem,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fCache : array of ILookahead;
|
||||
fNoFOLLOW : boolean;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar: IGrammar);
|
||||
destructor Destroy; override;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IRuleEndElem methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetnoFOLLOW: boolean;
|
||||
function GetCache(i: integer): ILookahead;
|
||||
|
||||
procedure SetnoFOLLOW( pnoFOLLOW: boolean);
|
||||
procedure SetCache(i:integer; pCache : ILookahead);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TRuleEndElem.Create(pGrammar: IGrammar);
|
||||
begin
|
||||
inherited Create( pGrammar);
|
||||
SetLength( fCache, fGrammar.MaxK +1);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TRuleEndElem.Destroy;
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
for i:=Low(fCache) to High(fCache) do
|
||||
fCache[i] := nil;
|
||||
|
||||
fCache := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TRuleEndElem.Generate;
|
||||
begin
|
||||
fGrammar.Generator.Gen(self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TRuleEndElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AsString
|
||||
// ============================================================================
|
||||
function TRuleEndElem.AsString: AnsiString;
|
||||
begin
|
||||
result := ' [RuleEnd]';
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IRuleEndElem implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetnoFOLLOW
|
||||
// ============================================================================
|
||||
function TRuleEndElem.GetnoFOLLOW: boolean;
|
||||
begin
|
||||
result := fNoFOLLOW;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetCache
|
||||
// ============================================================================
|
||||
function TRuleEndElem.GetCache(i: integer): ILookahead;
|
||||
begin
|
||||
result := fCache[i];
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetnoFOLLOW
|
||||
// ============================================================================
|
||||
procedure TRuleEndElem.SetnoFOLLOW(pnoFOLLOW: boolean);
|
||||
begin
|
||||
fNoFOLLOW := pnoFOLLOW;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetCache
|
||||
// ============================================================================
|
||||
procedure TRuleEndElem.SetCache(i: integer; pCache: ILookahead);
|
||||
begin
|
||||
fCache[i] := pCache;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,189 @@
|
||||
unit dpglib.RuleRefElem;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.Types,
|
||||
dpglib.AlternativeElem;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// TRuleRefElem class declaration
|
||||
// =========================================================================
|
||||
TRuleRefElem = class( TAlternativeElem,
|
||||
IRuleRefElem,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fTargetRule : AnsiString;
|
||||
fIdAssign : AnsiString;
|
||||
fArgs : AnsiString;
|
||||
fLabel : AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pAutoGenType: integer);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IAlternativeElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetLabel : AnsiString;
|
||||
procedure SetLabel( pLabel: AnsiString);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IRuleRefElem methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetTargetRule : AnsiString;
|
||||
function GetIdAssign : AnsiString;
|
||||
function GetArgs : AnsiString;
|
||||
|
||||
procedure SetTargetRule( pTargetRule : AnsiString);
|
||||
procedure SetIdAssign( pIdAssign : AnsiString);
|
||||
procedure SetArgs( pArgs : AnsiString);
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpglib.CodeGenerator,
|
||||
dpglib.DpgParserTokens;
|
||||
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TRuleRefElem.Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pAutoGenType: integer);
|
||||
begin
|
||||
inherited Create( pGrammar, pToken, pAutoGenType);
|
||||
|
||||
fTargetRule := pToken.TokenText;
|
||||
|
||||
if pToken.TokenType = TT_TOKENREF then
|
||||
fTargetRule := TCodeGenerator.encodeLexerRuleName( pToken.TokenText)
|
||||
else
|
||||
fTargetRule := pToken.TokenText;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TRuleRefElem.Generate;
|
||||
begin
|
||||
fGrammar.Generator.Gen(self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TRuleRefElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AsString
|
||||
// ============================================================================
|
||||
function TRuleRefElem.AsString: AnsiString;
|
||||
begin
|
||||
if fArgs <> '' then
|
||||
result := ' ' + fTargetRule + fArgs
|
||||
else
|
||||
result := ' ' + fTargetRule;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IAlternativeElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetLabel
|
||||
// ============================================================================
|
||||
function TRuleRefElem.GetLabel: AnsiString;
|
||||
begin
|
||||
result := fLabel;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetLabel
|
||||
// ============================================================================
|
||||
procedure TRuleRefElem.SetLabel(pLabel: AnsiString);
|
||||
begin
|
||||
fLabel := pLabel;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IRuleRefElem implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetTargetRule
|
||||
// ============================================================================
|
||||
function TRuleRefElem.GetTargetRule: AnsiString;
|
||||
begin
|
||||
result := fTargetRule;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetIdAssign
|
||||
// ============================================================================
|
||||
function TRuleRefElem.GetIdAssign: AnsiString;
|
||||
begin
|
||||
result := fIdAssign;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetArgs
|
||||
// ============================================================================
|
||||
function TRuleRefElem.GetArgs: AnsiString;
|
||||
begin
|
||||
result := fArgs;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetTargetRule
|
||||
// ============================================================================
|
||||
procedure TRuleRefElem.SetTargetRule(pTargetRule: AnsiString);
|
||||
begin
|
||||
fTargetRule := pTargetRule;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetIdAssign
|
||||
// ============================================================================
|
||||
procedure TRuleRefElem.SetIdAssign(pIdAssign: AnsiString);
|
||||
begin
|
||||
fIdAssign := pIdAssign;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetArgs
|
||||
// ============================================================================
|
||||
procedure TRuleRefElem.SetArgs(pArgs: AnsiString);
|
||||
begin
|
||||
fArgs := pArgs;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,184 @@
|
||||
unit dpglib.RuleSymbol;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.GrammarSymbol;
|
||||
|
||||
type
|
||||
TRuleSymbol = class( TGrammarSymbol, IRuleSymbol, IGrammarSymbol)
|
||||
protected
|
||||
fBlock : IRuleBlock;
|
||||
fDefined : boolean;
|
||||
fReferences : TInterfaceList;
|
||||
|
||||
fAccess : AnsiString;
|
||||
fComment : AnsiString;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IRuleSymbol
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function GetBlock : IRuleBlock;
|
||||
function GetDefined : boolean;
|
||||
function GetReferences : TInterfaceList;
|
||||
function GetAccess : AnsiString;
|
||||
function GetComment : AnsiString;
|
||||
function GetReference(i: integer): IRuleRefElem;
|
||||
|
||||
procedure SetBlock( pBlock : IRuleBlock);
|
||||
procedure SetDefined( pDefined : boolean);
|
||||
procedure SetAccess( pAccess : AnsiString);
|
||||
procedure SetComment( pComment : AnsiString);
|
||||
|
||||
procedure AddReference( pRef: IRuleRefElem);
|
||||
function ReferenceCount: integer;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils;
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TRuleSymbol.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
fReferences := TInterfaceList.Create;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TRuleSymbol.BeforeDestruction;
|
||||
begin
|
||||
FreeAndNil( fReferences);
|
||||
inherited
|
||||
end;
|
||||
|
||||
// @@@: IGrammarSymbol implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IGrammarSymbol implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Block
|
||||
// ================================================================================================
|
||||
function TRuleSymbol.GetBlock: IRuleBlock;
|
||||
begin
|
||||
result := fBlock;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Defined
|
||||
// ================================================================================================
|
||||
function TRuleSymbol.GetDefined: boolean;
|
||||
begin
|
||||
result := fDefined;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get References
|
||||
// ================================================================================================
|
||||
function TRuleSymbol.GetReferences: TInterfaceList;
|
||||
begin
|
||||
result := fReferences;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Reference
|
||||
// ================================================================================================
|
||||
function TRuleSymbol.GetReference(i: integer): IRuleRefElem;
|
||||
begin
|
||||
if (i>=0) and (i<fReferences.Count) then
|
||||
fReferences.Items[i].QueryInterface( IRuleRefElem, result);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Access
|
||||
// ================================================================================================
|
||||
function TRuleSymbol.GetAccess: AnsiString;
|
||||
begin
|
||||
result := fAccess;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Comment
|
||||
// ================================================================================================
|
||||
function TRuleSymbol.GetComment: AnsiString;
|
||||
begin
|
||||
result := fComment;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Block
|
||||
// ================================================================================================
|
||||
procedure TRuleSymbol.SetBlock(pBlock: IRuleBlock);
|
||||
begin
|
||||
fBlock := pBlock;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Defined
|
||||
// ================================================================================================
|
||||
procedure TRuleSymbol.SetDefined(pDefined: boolean);
|
||||
begin
|
||||
fDefined := pDefined;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Access
|
||||
// ================================================================================================
|
||||
procedure TRuleSymbol.SetAccess(pAccess: AnsiString);
|
||||
begin
|
||||
fAccess := pAccess;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Comment
|
||||
// ================================================================================================
|
||||
procedure TRuleSymbol.SetComment(pComment: AnsiString);
|
||||
begin
|
||||
fComment := pComment;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Add Reference
|
||||
// ================================================================================================
|
||||
procedure TRuleSymbol.AddReference(pRef: IRuleRefElem);
|
||||
begin
|
||||
fReferences.Add( pRef);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Reference Count
|
||||
// ================================================================================================
|
||||
function TRuleSymbol.ReferenceCount: integer;
|
||||
begin
|
||||
result := fReferences.Count;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,120 @@
|
||||
unit dpglib.StringLiteralElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.GrammarAtom;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TStringLiteralElem declaration
|
||||
// =========================================================================
|
||||
TStringLiteralElem = class(TGrammarAtom,
|
||||
IStringLiteralElem,
|
||||
IGrammarAtom,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fProcessedAtomText : AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pAutoGenType: integer);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IStringLiteralElem methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetProcessedAtomText: AnsiString;
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TStringLiteralElem.Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pAutoGenType: integer);
|
||||
var
|
||||
lg: ILexerGrammar;
|
||||
ts: ITokenSymbol;
|
||||
|
||||
begin
|
||||
inherited Create( pGrammar, pToken, pAutoGenType);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Lexer does not have token types for AnsiString literals
|
||||
// ---------------------------------------------------------------
|
||||
if pGrammar.QueryInterface( ILexerGrammar, lg) <> S_OK then
|
||||
begin
|
||||
ts := fGrammar.TokenManager.TokenSymbol[ fAtomText];
|
||||
|
||||
if ts = nil then
|
||||
fGrammar.Tool.Error( 'Undefined literal: ' + String(fAtomText),
|
||||
fGrammar.GrammarFile,
|
||||
pToken.TokenLine,
|
||||
pToken.TokenColumn)
|
||||
else
|
||||
fTokenType := ts.TokenType;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Process the AnsiString literal text by removing quotes and escaping
|
||||
// characters. If a lexical grammar, add the characters to the
|
||||
// char vocabulary.
|
||||
// (Later if I really need it....)
|
||||
// ---------------------------------------------------------------
|
||||
fProcessedAtomText := Copy(fAtomText,2,Length(fAtomText)-2);
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TStringLiteralElem.Generate;
|
||||
begin
|
||||
fGrammar.Generator.Gen( self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TStringLiteralElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look(pK, self);
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IStringLiteralElem implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetProcessedAtomText
|
||||
// ============================================================================
|
||||
function TStringLiteralElem.GetProcessedAtomText: AnsiString;
|
||||
begin
|
||||
result := fProcessedAtomText;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,75 @@
|
||||
unit dpglib.StringSymbol;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpglib.types,
|
||||
dpglib.TokenSymbol;
|
||||
|
||||
type
|
||||
TStringSymbol = class( TTokenSymbol,
|
||||
IStringSymbol,
|
||||
ITokenSymbol,
|
||||
IGrammarSymbol)
|
||||
protected
|
||||
fLabel: AnsiString;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IGrammarSymbol
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function Clone: ITokenSymbol;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IStringSymbol
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function GetLabel: AnsiString;
|
||||
procedure SetLabel( pLabel: AnsiString);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// @@@: IStringSymbol implementation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IStringSymbol implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Label
|
||||
// ================================================================================================
|
||||
function TStringSymbol.GetLabel: AnsiString;
|
||||
begin
|
||||
result := fLabel;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Label
|
||||
// ================================================================================================
|
||||
procedure TStringSymbol.SetLabel(pLabel: AnsiString);
|
||||
begin
|
||||
fLabel := pLabel;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clone
|
||||
// ================================================================================================
|
||||
function TStringSymbol.Clone: ITokenSymbol;
|
||||
var
|
||||
ss: TStringSymbol;
|
||||
|
||||
begin
|
||||
ss := TStringSymbol.Create( fID);
|
||||
|
||||
ss.fTokenType := fTokenType;
|
||||
ss.fParaphrase := fParaphrase;
|
||||
ss.fASTNodeType := fASTNodeType;
|
||||
ss.fLabel := fLabel;
|
||||
|
||||
result := ss;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,60 @@
|
||||
unit dpglib.SynPredBlock;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.AlternativeBlock;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TSynPredBlock declaration
|
||||
// =========================================================================
|
||||
TSynPredBlock = class( TAlternativeBlock,
|
||||
ISynPredBlock,
|
||||
IAlternativeBlock,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpglib.lookahead;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// Generate
|
||||
// ----------------------------------------------------------------------------
|
||||
procedure TSynPredBlock.Generate;
|
||||
begin
|
||||
fGrammar.Generator.Gen( self);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Look
|
||||
// ----------------------------------------------------------------------------
|
||||
function TSynPredBlock.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := TLookahead.Create;
|
||||
// result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ToString
|
||||
// ----------------------------------------------------------------------------
|
||||
function TSynPredBlock.AsString: AnsiString;
|
||||
begin
|
||||
result := inherited AsString + '=>';
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,622 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.tokenLexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenLexer;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes,
|
||||
SysUtils,
|
||||
dpglib.TokenLexerTokens,
|
||||
dpgrtl.lexer,
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TTokenLexer declaration
|
||||
// =========================================================================
|
||||
TTokenLexer = class( TLexer)
|
||||
|
||||
public // Protected grammar rules
|
||||
// Must callable from parser too
|
||||
procedure mDIGIT ( pCreate: boolean);
|
||||
procedure mXDIGIT ( pCreate: boolean);
|
||||
|
||||
public // Public grammar rules
|
||||
procedure mLPAREN ( pCreate: boolean);
|
||||
procedure mRPAREN ( pCreate: boolean);
|
||||
procedure mASSIGN ( pCreate: boolean);
|
||||
procedure mSTRING ( pCreate: boolean);
|
||||
procedure mID ( pCreate: boolean);
|
||||
procedure mINT ( pCreate: boolean);
|
||||
procedure mWS ( pCreate: boolean);
|
||||
procedure mSLCOMMENT ( pCreate: boolean);
|
||||
procedure mMLCOMMENT ( pCreate: boolean);
|
||||
|
||||
public
|
||||
function NextToken: IToken; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpgrtl.exception,
|
||||
dpgrtl.token;
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// mLPAREN
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mLPAREN( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_LPAREN;
|
||||
|
||||
match('(');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mRPAREN
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mRPAREN( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_RPAREN;
|
||||
|
||||
match(')');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mASSIGN
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mASSIGN( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_ASSIGN;
|
||||
|
||||
match('=');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mSTRING
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mSTRING( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_STRING;
|
||||
|
||||
match('"');
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in [#1..'!','#'..#255])) then
|
||||
begin
|
||||
matchNot('"');
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
match('"');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mDIGIT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mDIGIT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_DIGIT;
|
||||
|
||||
match( ['0'..'9']);
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mXDIGIT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mXDIGIT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_XDIGIT;
|
||||
|
||||
if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
match( ['0'..'9']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['a'..'f'])) then
|
||||
begin
|
||||
match( ['a'..'f']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'F'])) then
|
||||
begin
|
||||
match( ['A'..'F']);
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), ['0'..'9','A'..'F','a'..'f'], InputState.FileName, InputState.Line, InputState.Column);
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mID
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mID( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_ID;
|
||||
|
||||
if (( LA(1) in ['a'..'z'])) then
|
||||
begin
|
||||
match( ['a'..'z']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'Z'])) then
|
||||
begin
|
||||
match( ['A'..'Z']);
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), ['A'..'Z','a'..'z'], InputState.FileName, InputState.Line, InputState.Column);
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in ['a'..'z'])) then
|
||||
begin
|
||||
match( ['a'..'z']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'Z'])) then
|
||||
begin
|
||||
match( ['A'..'Z']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['_'])) then
|
||||
begin
|
||||
match('_');
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
match( ['0'..'9']);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mINT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mINT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_cnt_15: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_INT;
|
||||
|
||||
_cnt_15 := 0;
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
mDIGIT(false);
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
if _cnt_15 >= 1 then
|
||||
break
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), ['0'..'9'], InputState.FileName, InputState.Line, InputState.Column);
|
||||
end;
|
||||
|
||||
INC(_cnt_15);
|
||||
end;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mWS
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mWS( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_WS;
|
||||
|
||||
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
||||
begin
|
||||
match(#13);
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [' '])) then
|
||||
begin
|
||||
match(' ');
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#9])) then
|
||||
begin
|
||||
match(#9);
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#13])) then
|
||||
begin
|
||||
match(#13);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#10])) then
|
||||
begin
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), [#9..#10,#13,' '], InputState.FileName, InputState.Line, InputState.Column);
|
||||
_ttype := TT_SKIP;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mSLCOMMENT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mSLCOMMENT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_SLCOMMENT;
|
||||
|
||||
match('//');
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
|
||||
begin
|
||||
match( [#1..#9,#11..#12,#14..#255]);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
||||
begin
|
||||
match(#13);
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#13])) then
|
||||
begin
|
||||
match(#13);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#10])) then
|
||||
begin
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), [#10,#13], InputState.FileName, InputState.Line, InputState.Column);
|
||||
_ttype := TT_SKIP;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mMLCOMMENT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mMLCOMMENT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_MLCOMMENT;
|
||||
|
||||
match('(*');
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
// non-greedy exit test
|
||||
if( LA(1) in ['*']) and (LA(2) in [')']) then
|
||||
break;
|
||||
|
||||
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
||||
begin
|
||||
match(#13);
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#13])) then
|
||||
begin
|
||||
match(#13);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#10])) then
|
||||
begin
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
|
||||
begin
|
||||
match( [#1..#9,#11..#12,#14..#255]);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
match('*)');
|
||||
_ttype := TT_SKIP;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// NextToken
|
||||
// ----------------------------------------------------------------------------
|
||||
function TTokenLexer.NextToken : IToken;
|
||||
var
|
||||
_first : TCharSet;
|
||||
|
||||
begin
|
||||
_first := [#9..#10,#13,' ','"','('..')','/'..'9','=','A'..'Z','a'..'z'];
|
||||
|
||||
while( true) do
|
||||
begin
|
||||
ResetText;
|
||||
|
||||
try
|
||||
if (( LA(1) in ['(']) and (LA(2) in ['*'])) then
|
||||
begin
|
||||
mMLCOMMENT(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['('])) then
|
||||
begin
|
||||
mLPAREN(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [')'])) then
|
||||
begin
|
||||
mRPAREN(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['='])) then
|
||||
begin
|
||||
mASSIGN(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['"'])) then
|
||||
begin
|
||||
mSTRING(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'Z','a'..'z'])) then
|
||||
begin
|
||||
mID(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
mINT(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#9..#10,#13,' '])) then
|
||||
begin
|
||||
mWS(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['/'])) then
|
||||
begin
|
||||
mSLCOMMENT(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
if LA(1) = EOF_CHAR then
|
||||
begin
|
||||
uponEof;
|
||||
result := TToken.Create(TT_EOF);
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create(LA(1), _first, InputState.FileName, InputState.Line, InputState.Column);
|
||||
end;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// If we found a SKIP token, then try again...
|
||||
// --------------------------------------------------------------
|
||||
if result = nil then
|
||||
continue;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Now we have a valid token, so exit the function
|
||||
// --------------------------------------------------------------
|
||||
break;
|
||||
|
||||
except
|
||||
Raise;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,26 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.tokenLexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenLexerTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_ID = 10;
|
||||
TT_STRING = 7;
|
||||
TT_EOF = 1;
|
||||
TT_XDIGIT = 9;
|
||||
TT_SLCOMMENT = 13;
|
||||
TT_ASSIGN = 6;
|
||||
TT_WS = 12;
|
||||
TT_LPAREN = 4;
|
||||
TT_RPAREN = 5;
|
||||
TT_DIGIT = 8;
|
||||
TT_MLCOMMENT = 14;
|
||||
TT_INT = 11;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,427 @@
|
||||
unit dpglib.TokenManager;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.Contnrs,
|
||||
Generics.Collections,
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.TokenSymbol;
|
||||
|
||||
type
|
||||
TTokenManager = class( TInterfacedObject, ITokenManager)
|
||||
protected
|
||||
fName : AnsiString;
|
||||
fMaxToken : byte;
|
||||
fReadOnly : boolean;
|
||||
fTool : ITool;
|
||||
|
||||
// fVocabulary : TStringList;
|
||||
|
||||
fVocabulary : TTokenIdMap;
|
||||
fHashTable : TStringList;
|
||||
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// ITokenManager methods
|
||||
// ------------------------------------------------------------
|
||||
function GetName : AnsiString;
|
||||
function GetReadOnly : boolean;
|
||||
function GetMaxTokenType : byte;
|
||||
function GetNextTokenType : byte;
|
||||
function GetVocabulary : TTokenIdMap;
|
||||
|
||||
function GetTokenStringAt( i : integer) : AnsiString;
|
||||
function GetTokenSymbolByType( t : integer) : ITokenSymbol;
|
||||
function GetTokenSymbolAt( i : integer) : ITokenSymbol;
|
||||
function GetTokenSymbol( Name : AnsiString) : ITokenSymbol;
|
||||
function GetTokenDefined( Name : AnsiString) : boolean;
|
||||
|
||||
procedure SetName( Name : AnsiString);
|
||||
procedure SetReadOnly( ReadOnly : boolean);
|
||||
procedure SetMaxTokenType( TokenType : byte);
|
||||
|
||||
function Clone : ITokenManager;
|
||||
|
||||
function TokenSymbolKeys : TStringList;
|
||||
function TokenSymbolElems : TInterfaceList;
|
||||
|
||||
procedure MapToTokenSymbol( Name: AnsiString; TS: ITokenSymbol);
|
||||
procedure Define( TS: ITokenSymbol);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pName: AnsiString; pTool: ITool);
|
||||
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils;
|
||||
|
||||
type
|
||||
TTokenManagerObject = class
|
||||
private
|
||||
fTokenSymbol : ITokenSymbol;
|
||||
|
||||
public
|
||||
constructor Create( TS: ITokenSymbol);
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TTokenManager.Create( pName: AnsiString; pTool: ITool);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fName := pName;
|
||||
fTool := pTool;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TTokenManager.AfterConstruction;
|
||||
var
|
||||
ts: ITokenSymbol;
|
||||
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fMaxToken := TT_USER;
|
||||
fReadOnly := false;
|
||||
|
||||
// fVocabulary := TStringList.Create;
|
||||
fVocabulary := TTokenIdMap.Create;
|
||||
fHashTable := TStringList.Create(true);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Define EOF symbol
|
||||
// ---------------------------------------------------------------
|
||||
ts := TTokenSymbol.Create('EOF');
|
||||
ts.TokenType:= TT_EOF;
|
||||
|
||||
Define( ts);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Define <null-tree-lookahead> but only in the vocabulary vector.
|
||||
// ---------------------------------------------------------------
|
||||
// fVocabulary.Add('NULL_TREE_LOOKAHEAD=' + IntToStr(TT_NTLA));
|
||||
fVocabulary.Add('NULL_TREE_LOOKAHEAD=', TT_NTLA);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TTokenManager.BeforeDestruction;
|
||||
var
|
||||
ts : ITokenSymbol;
|
||||
i : integer;
|
||||
|
||||
begin
|
||||
// for i:=0 to fHashTable.Count -1 do
|
||||
// begin
|
||||
// ts := ITokenSymbol( pointer( fHashTable.Objects[i]));
|
||||
// ts := nil;
|
||||
// end;
|
||||
|
||||
FreeAndNil( fVocabulary);
|
||||
FreeAndNil( fHashTable);
|
||||
|
||||
fTool := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// @@@: ITokenManager implementation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// ITokenManager implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Name
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetName: AnsiString;
|
||||
begin
|
||||
result := fName;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get ReadOnly
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetReadOnly: boolean;
|
||||
begin
|
||||
result := fReadOnly;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token String at
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetTokenStringAt(i: integer): AnsiString;
|
||||
begin
|
||||
if (i>=0) and (i<fHashTable.Count)
|
||||
then result := AnsiString(fHashTable.Strings[i])
|
||||
else result := '';
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Symbol at
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetTokenSymbolAt(i: integer): ITokenSymbol;
|
||||
begin
|
||||
if (i>=0) and (i<fHashTable.Count)
|
||||
then result := (fHashTable.Objects[i] as TTokenManagerObject).fTokenSymbol
|
||||
else result := nil;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Symbol
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetTokenSymbol(Name: AnsiString): ITokenSymbol;
|
||||
var
|
||||
i: integer;
|
||||
p: pointer;
|
||||
|
||||
begin
|
||||
i := fHashTable.IndexOf( String(Name));
|
||||
|
||||
if i>=0
|
||||
then result := (fHashTable.Objects[i] as TTokenManagerObject).fTokenSymbol
|
||||
else result := nil;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Symbol By ID
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetTokenSymbolByType( t: integer): ITokenSymbol;
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
for i:=0 to fHashTable.Count -1 do
|
||||
begin
|
||||
result := (fHashTable.Objects[i] as TTokenManagerObject).fTokenSymbol;
|
||||
//ITokenSymbol( pointer( fHashTable.Objects[i]));
|
||||
|
||||
if result.TokenType = t then
|
||||
exit;
|
||||
end;
|
||||
|
||||
result := nil;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Defined
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetTokenDefined(Name: AnsiString): boolean;
|
||||
begin
|
||||
result := fHashTable.IndexOf( String(Name)) >= 0
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Max Token Type
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetMaxTokenType: byte;
|
||||
begin
|
||||
result := fMaxToken -1
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Next Token Type
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetNextTokenType: byte;
|
||||
begin
|
||||
result := fMaxToken;
|
||||
INC( fMaxToken)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Vocabulary
|
||||
// ================================================================================================
|
||||
function TTokenManager.GetVocabulary: TTokenIdMap;
|
||||
begin
|
||||
result := fVocabulary
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Name
|
||||
// ================================================================================================
|
||||
procedure TTokenManager.SetName(Name: AnsiString);
|
||||
begin
|
||||
fName := Name
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set ReadOnly
|
||||
// ================================================================================================
|
||||
procedure TTokenManager.SetReadOnly(ReadOnly: boolean);
|
||||
begin
|
||||
fReadOnly := ReadOnly
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Max TokenType
|
||||
// ================================================================================================
|
||||
procedure TTokenManager.SetMaxTokenType(TokenType: byte);
|
||||
begin
|
||||
fMaxToken := TokenType
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clone
|
||||
// ================================================================================================
|
||||
function TTokenManager.Clone: ITokenManager;
|
||||
var
|
||||
i : integer;
|
||||
ts : ITokenSymbol;
|
||||
|
||||
begin
|
||||
result := TTokenManager.Create( fName, fTool);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Clone hash table (Don't use Assign here!!!!!)
|
||||
// ---------------------------------------------------------------
|
||||
for i:=0 to fHashTable.Count -1 do
|
||||
begin
|
||||
ts := (fHashTable.Objects[i] as TTokenManagerObject).fTokenSymbol;
|
||||
|
||||
if ts <> nil then
|
||||
result.Define( ts.Clone);
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Clone vocabulary
|
||||
// ---------------------------------------------------------------
|
||||
// for i:=0 to fVocabulary.Count -1 do
|
||||
// result.Vocabulary.Add( fVocabulary.Strings[i]);
|
||||
Raise Exception.Create('Check this!!!');
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Set max token type
|
||||
// ---------------------------------------------------------------
|
||||
result.MaxTokenType := fMaxToken;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// TokenSymbolKeys
|
||||
// ================================================================================================
|
||||
function TTokenManager.TokenSymbolKeys: TStringList;
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
result := TStringList.Create;
|
||||
|
||||
for i:=0 to fHashTable.Count -1 do
|
||||
result.Add( fHashTable.Strings[i]);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// TokenSymbolElems
|
||||
// ================================================================================================
|
||||
function TTokenManager.TokenSymbolElems: TInterfaceList;
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
result := TInterfaceList.Create;
|
||||
|
||||
for i:=0 to fHashTable.Count-1 do
|
||||
result.Add( (fHashTable.Objects[i] as TTokenManagerObject).fTokenSymbol);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Define
|
||||
// ================================================================================================
|
||||
procedure TTokenManager.Define(TS: ITokenSymbol);
|
||||
begin
|
||||
if not fVocabulary.ContainsKey(TS.ID) then
|
||||
begin
|
||||
fVocabulary.Add( TS.ID, TS.TokenType);
|
||||
MapToTokenSymbol( TS.ID, TS);
|
||||
|
||||
if fMaxToken <= TS.TokenType then
|
||||
fMaxToken := TS.TokenType+1;
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Add the symbol to the vocabulary vector and hash table
|
||||
// ---------------------------------------------------------------
|
||||
// if fVocabulary.IndexOfName( String(TS.ID)) < 0 then
|
||||
// begin
|
||||
// fVocabulary.Add( String(TS.ID) + '=' + IntToStr( TS.TokenType));
|
||||
// MapToTokenSymbol( TS.ID, TS);
|
||||
//
|
||||
// if fMaxToken <= TS.TokenType then
|
||||
// fMaxToken := TS.TokenType+1;
|
||||
// end;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Map to Token Symbol
|
||||
//
|
||||
// Map a label or a AnsiString to an existing token symbol.
|
||||
// ================================================================================================
|
||||
procedure TTokenManager.MapToTokenSymbol( Name: AnsiString; TS: ITokenSymbol);
|
||||
begin
|
||||
TS._AddRef;
|
||||
fHashTable.AddObject( String(Name), TTokenManagerObject.Create(TS));
|
||||
|
||||
//// replace vocabulary item if it does exist.
|
||||
// idx := fVocabulary.IndexOfName(String(TS.ID));
|
||||
//
|
||||
// if idx >= 0 then
|
||||
// fVocabulary[idx] := pName +'='+ IntToStr( pTS.TokenType);
|
||||
end;
|
||||
|
||||
{ TTokenManagerObject }
|
||||
|
||||
// @@@: TTokenManagerObject +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// TTokenManagerObject
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TTokenManagerObject.Create(TS: ITokenSymbol);
|
||||
begin
|
||||
inherited Create;
|
||||
fTokenSymbol := TS
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Destructor
|
||||
// ================================================================================================
|
||||
destructor TTokenManagerObject.Destroy;
|
||||
begin
|
||||
fTokenSymbol := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.tokenParser.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenParser;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes,
|
||||
SysUtils,
|
||||
dpglib.StringSymbol,
|
||||
dpglib.TokenParserTokens,
|
||||
dpglib.TokenSymbol,
|
||||
dpglib.Types,
|
||||
dpgrtl.llkparser,
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TTokenParser declaration
|
||||
// =========================================================================
|
||||
TTokenParser = class( TLLkParser)
|
||||
|
||||
public // Public grammar rules
|
||||
procedure tokenFile ( tm:ITokenManager);
|
||||
procedure tokenLine ( tm:ITokenManager);
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpgrtl.exception,
|
||||
dpgrtl.token;
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// tokenFile
|
||||
// ============================================================================
|
||||
procedure TTokenParser.tokenFile( tm:ITokenManager);
|
||||
var
|
||||
name: IToken;
|
||||
|
||||
begin
|
||||
|
||||
name := LT(1);
|
||||
match(TT_ID);
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in [TT_STRING,TT_ID])) then
|
||||
begin
|
||||
tokenLine(tm);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// tokenLine
|
||||
// ============================================================================
|
||||
procedure TTokenParser.tokenLine( tm:ITokenManager);
|
||||
var
|
||||
i: IToken;
|
||||
id: IToken;
|
||||
id2: IToken;
|
||||
lab: IToken;
|
||||
para: IToken;
|
||||
s1: IToken;
|
||||
s2: IToken;
|
||||
t : IToken;
|
||||
s : IToken;
|
||||
v : integer;
|
||||
sl: IStringSymbol;
|
||||
ts: ITokenSymbol;
|
||||
x : AnsiString;
|
||||
|
||||
begin
|
||||
|
||||
t := nil;
|
||||
s := nil;
|
||||
if (( LA(1) in [TT_STRING])) then
|
||||
begin
|
||||
s1 := LT(1);
|
||||
match(TT_STRING);
|
||||
s := s1;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_ASSIGN]) and (LA(3) in [TT_STRING])) then
|
||||
begin
|
||||
lab := LT(1);
|
||||
match(TT_ID);
|
||||
t := lab;
|
||||
match(TT_ASSIGN);
|
||||
s2 := LT(1);
|
||||
match(TT_STRING);
|
||||
s := s2;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_LPAREN])) then
|
||||
begin
|
||||
id := LT(1);
|
||||
match(TT_ID);
|
||||
t := id;
|
||||
match(TT_LPAREN);
|
||||
para := LT(1);
|
||||
match(TT_STRING);
|
||||
match(TT_RPAREN);
|
||||
end
|
||||
|
||||
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_ASSIGN]) and (LA(3) in [TT_INT])) then
|
||||
begin
|
||||
id2 := LT(1);
|
||||
match(TT_ID);
|
||||
t := id2;
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedToken.Create( LT(1), [TT_STRING,TT_ID], InputState.FileName);
|
||||
match(TT_ASSIGN);
|
||||
i := LT(1);
|
||||
match(TT_INT);
|
||||
v := StrToIntDef( i.TokenText, -1);
|
||||
|
||||
if s <> nil then
|
||||
begin
|
||||
ts := TStringSymbol.Create( s.TokenText);
|
||||
ts.TokenType := v;
|
||||
tm.Define(ts);
|
||||
|
||||
if t <> nil then
|
||||
begin
|
||||
ts := tm.TokenSymbol[s.TokenText];
|
||||
ts.QueryInterface( IStringSymbol, sl);
|
||||
sl.Lbl := t.TokenText;
|
||||
|
||||
tm.MapToTokenSymbol( t.TokenText, sl);
|
||||
end;
|
||||
end
|
||||
|
||||
else if t <> nil then
|
||||
begin
|
||||
x := Copy( t.TokenText, 4, Length( t.TokenText)-3);
|
||||
ts := TTokenSymbol.Create( x);
|
||||
ts.TokenType := v;
|
||||
tm.Define( ts);
|
||||
|
||||
if para <> nil then
|
||||
begin
|
||||
ts := tm.TokenSymbol[ t.TokenText];
|
||||
ts.Paraphrase := para.TokenText;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,26 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.tokenParser.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenParserTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_ID = 10;
|
||||
TT_STRING = 7;
|
||||
TT_EOF = 1;
|
||||
TT_SLCOMMENT = 13;
|
||||
TT_XDIGIT = 9;
|
||||
TT_ASSIGN = 6;
|
||||
TT_WS = 12;
|
||||
TT_LPAREN = 4;
|
||||
TT_RPAREN = 5;
|
||||
TT_DIGIT = 8;
|
||||
TT_MLCOMMENT = 14;
|
||||
TT_INT = 11;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,168 @@
|
||||
unit dpglib.TokenRangeElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.Types,
|
||||
dpglib.AlternativeElem;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TTokenRangeElem declaration
|
||||
// =========================================================================
|
||||
TTokenRangeElem = class( TAlternativeElem,
|
||||
ITokenRangeElem,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Members
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
fLabel : AnsiString;
|
||||
fBegin : integer;
|
||||
fEnd : integer;
|
||||
fBeginText : AnsiString;
|
||||
fEndText : AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pToken1 : IToken;
|
||||
pToken2 : IToken;
|
||||
pAutoGenType: integer);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IAlternativeElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetLabel : AnsiString;
|
||||
procedure SetLabel( pLabel: AnsiString);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// ITokenRangeElem methods
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetBeginToken : integer;
|
||||
function GetEndToken : integer;
|
||||
function GetBeginText : AnsiString;
|
||||
function GetEndText : AnsiString;
|
||||
end;
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TTokenRangeElem.Create( pGrammar : IGrammar;
|
||||
pToken1 : IToken;
|
||||
pToken2 : IToken;
|
||||
pAutoGenType: integer);
|
||||
begin
|
||||
inherited Create( pGrammar, pToken1, pAutoGenType);
|
||||
|
||||
fBegin := fGrammar.TokenManager.TokenSymbol[pToken1.TokenText].TokenType;
|
||||
fEnd := fGrammar.TokenManager.TokenSymbol[pToken2.TokenText].TokenType;
|
||||
|
||||
fBeginText := pToken1.TokenText;
|
||||
fEndText := pToken2.TokenText;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TTokenRangeElem.Generate;
|
||||
begin
|
||||
fGrammar.Generator.Gen( self);
|
||||
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TTokenRangeElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AsString
|
||||
// ============================================================================
|
||||
function TTokenRangeElem.AsString: AnsiString;
|
||||
begin
|
||||
if fLabel <> '' then
|
||||
result := ' ' + fLabel + ':' + fBeginText + '..' + fEndText
|
||||
else
|
||||
result := ' ' + fBeginText + '..' + fEndText;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IAlternativeElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetLabel
|
||||
// ============================================================================
|
||||
function TTokenRangeElem.GetLabel: AnsiString;
|
||||
begin
|
||||
result := fLabel;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// SetLabel
|
||||
// ============================================================================
|
||||
procedure TTokenRangeElem.SetLabel(pLabel: AnsiString);
|
||||
begin
|
||||
fLabel := pLabel;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// ITokenRangeElem implementation
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// GetBeginToken
|
||||
// ============================================================================
|
||||
function TTokenRangeElem.GetBeginToken: integer;
|
||||
begin
|
||||
result := fBegin;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetEndToken
|
||||
// ============================================================================
|
||||
function TTokenRangeElem.GetEndToken: integer;
|
||||
begin
|
||||
result := fEnd;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetBeginText
|
||||
// ============================================================================
|
||||
function TTokenRangeElem.GetBeginText: AnsiString;
|
||||
begin
|
||||
result := fBeginText;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// GetEndText
|
||||
// ============================================================================
|
||||
function TTokenRangeElem.GetEndText: AnsiString;
|
||||
begin
|
||||
result := fEndText;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,102 @@
|
||||
unit dpglib.TokenRefElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.Types,
|
||||
dpglib.GrammarAtom;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TTokenRefElem declaration
|
||||
// =========================================================================
|
||||
TTokenRefElem = class( TGrammarAtom,
|
||||
ITokenRefElem,
|
||||
IGrammarAtom,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pInverted : boolean;
|
||||
pAutoGenType: integer);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
end;
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TTokenRefElem.Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pInverted : boolean;
|
||||
pAutoGenType: integer);
|
||||
var
|
||||
ts: ITokenSymbol;
|
||||
|
||||
begin
|
||||
inherited Create( pGrammar, pToken, pAutoGenType);
|
||||
|
||||
fNot := pInverted;
|
||||
ts := fGrammar.TokenManager.TokenSymbol[fAtomText];
|
||||
|
||||
if ts <> nil then
|
||||
begin
|
||||
fTokenType := ts.TokenType;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Set the AST node type to whatever was set in tokens {...}
|
||||
// section (if anything).
|
||||
// After this is create, the element option can set this.
|
||||
// ------------------------------------------------------------
|
||||
SetASTNodeType( ts.ASTNodeType);
|
||||
end
|
||||
else
|
||||
begin
|
||||
fGrammar.Tool.Error( 'Undefined token symbol: ' + String(fAtomText),
|
||||
fGrammar.GrammarFile,
|
||||
pToken.TokenLine,
|
||||
pToken.TokenColumn);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TTokenRefElem.Generate;
|
||||
var
|
||||
_self: ITokenRefElem;
|
||||
|
||||
begin
|
||||
_self := self;
|
||||
fGrammar.Generator.Gen(_self);
|
||||
|
||||
// fGrammar.Generator.Gen(self as ITokenRefElem);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TTokenRefElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,125 @@
|
||||
unit dpglib.TokenSymbol;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.GrammarSymbol;
|
||||
|
||||
type
|
||||
TTokenSymbol = class( TGrammarSymbol, ITokenSymbol, IGrammarSymbol)
|
||||
protected
|
||||
fTokenType : integer;
|
||||
fParaphrase : AnsiString;
|
||||
fASTNodeType : AnsiString;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
constructor Create( ID: AnsiString);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IdpgTokenSymbol methods
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function GetTokenType : integer;
|
||||
function GetParaphrase : AnsiString;
|
||||
function GetASTNodeType : AnsiString;
|
||||
|
||||
procedure SetTokenType( TokenType : integer);
|
||||
procedure SetParaphrase( Paraphrase : AnsiString);
|
||||
procedure SetASTNodeType( ASTNodeType : AnsiString);
|
||||
|
||||
function Clone: ITokenSymbol;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TTokenSymbol.Create(ID: AnsiString);
|
||||
begin
|
||||
inherited Create( ID);
|
||||
fTokenType := TT_INVALID;
|
||||
end;
|
||||
|
||||
// @@@: ITokenSymbol implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// ITokenSymbol implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Token Type
|
||||
// ================================================================================================
|
||||
function TTokenSymbol.GetTokenType: integer;
|
||||
begin
|
||||
result := fTokenType;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Paraphrase
|
||||
// ================================================================================================
|
||||
function TTokenSymbol.GetParaphrase: AnsiString;
|
||||
begin
|
||||
result := fParaphrase;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get AST Node Type
|
||||
// ================================================================================================
|
||||
function TTokenSymbol.GetASTNodeType: AnsiString;
|
||||
begin
|
||||
result := fASTNodeType;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Token Type
|
||||
// ================================================================================================
|
||||
procedure TTokenSymbol.SetTokenType(TokenType: integer);
|
||||
begin
|
||||
fTokenType := TokenType;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Paraphrase
|
||||
// ================================================================================================
|
||||
procedure TTokenSymbol.SetParaphrase(Paraphrase: AnsiString);
|
||||
begin
|
||||
fParaphrase := Paraphrase;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set AST Node Type
|
||||
// ================================================================================================
|
||||
procedure TTokenSymbol.SetASTNodeType(ASTNodeType: AnsiString);
|
||||
begin
|
||||
fASTNodeType := ASTNodeType;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clone
|
||||
// ================================================================================================
|
||||
function TTokenSymbol.Clone: ITokenSymbol;
|
||||
begin
|
||||
result := TTokenSymbol.Create( fID);
|
||||
result.TokenType := fTokenType;
|
||||
result.Paraphrase := fParaphrase;
|
||||
result.ASTNodeType:= fASTNodeType;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,554 @@
|
||||
unit dpglib.Tool;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.SysUtils,
|
||||
dpgrtl.types,
|
||||
dpgrtl.exception,
|
||||
dpglib.Types;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TTool declaration
|
||||
// =========================================================================
|
||||
TTool = class( TInterfacedObject,
|
||||
ITool)
|
||||
|
||||
protected
|
||||
fModuleStream : TStream;
|
||||
fModuleName : AnsiString;
|
||||
fOutputDir : AnsiString;
|
||||
fExchangeDir : AnsiString;
|
||||
fErrorHandler : IToolErrorHandler;
|
||||
|
||||
protected
|
||||
fWarningCount : integer;
|
||||
fErrorCount : integer;
|
||||
|
||||
protected
|
||||
// ------------------------------------------------------------
|
||||
// members
|
||||
// ------------------------------------------------------------
|
||||
fGrammarFile : AnsiString;
|
||||
fGrammar : IGrammar;
|
||||
|
||||
function GetWarningCount : integer;
|
||||
function GetErrorCount : integer;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Exception handling
|
||||
// ------------------------------------------------------------
|
||||
procedure exMismatchedChar( mc: EMismatchedChar);
|
||||
procedure exMismatchedToken( mt: EMismatchedToken);
|
||||
|
||||
procedure dumpSets( pGrammar : IGrammar;
|
||||
pLexical : boolean;
|
||||
pSets : TInterfaceList;
|
||||
pDepth : integer);
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ------------------------------------------------------------
|
||||
constructor Create( pFile : AnsiString;
|
||||
pErrorHandler : IToolErrorHandler); overload;
|
||||
|
||||
constructor Create( pModuleStream : TStream;
|
||||
pModuleName : AnsiString;
|
||||
pOutputDir : AnsiString;
|
||||
pExchangeDir : AnsiString;
|
||||
pErrorHandler : IToolErrorHandler); overload;
|
||||
|
||||
destructor Destroy; override;
|
||||
|
||||
public
|
||||
// ------------------------------------------------------------
|
||||
// ITool methods
|
||||
// ------------------------------------------------------------
|
||||
procedure Go;
|
||||
function Get_ErrorHandler: IToolErrorHandler;
|
||||
|
||||
procedure Debug( pMessage : AnsiString);
|
||||
procedure Error( pMessage : AnsiString;
|
||||
pFileName: AnsiString = '';
|
||||
pLine : integer = 0;
|
||||
pColumn : integer = 0);
|
||||
|
||||
procedure Warning( pMessage : AnsiString;
|
||||
pFileName: AnsiString = '';
|
||||
pLine : integer = 0;
|
||||
pColumn : integer = 0);
|
||||
|
||||
procedure Panic( pMessage : AnsiString);
|
||||
|
||||
procedure WarnAltAmbiguity( pGrammar : IGrammar;
|
||||
pBlock : IAlternativeBlock;
|
||||
pLexical : boolean;
|
||||
pDepth : integer;
|
||||
pSets : TInterfaceList;
|
||||
pAltIdx1 : integer;
|
||||
pAltIdx2 : integer);
|
||||
|
||||
procedure WarnAltExitAmbiguity( pGrammar : IGrammar;
|
||||
pBlock : IBlockWithImpliedExitPath;
|
||||
pLexical : boolean;
|
||||
pDepth : integer;
|
||||
pSets : TInterfaceList;
|
||||
pAltIdx : integer);
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpglib.DpgLexer,
|
||||
dpglib.DpgParser,
|
||||
dpglib.CodeGenerator,
|
||||
dpglib.Utils,
|
||||
dpglib.LLkAnalyzer,
|
||||
dpglib.GrammarMaker,
|
||||
dpglib.DelphiGenerator,
|
||||
dpglib.PrettyPrinter;
|
||||
// dpgExceptionPanic;
|
||||
|
||||
// ****************************************************************************
|
||||
//
|
||||
// Constructor/destructor
|
||||
//
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TTool.Create( pFile : AnsiString;
|
||||
pErrorHandler : IToolErrorHandler);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
fGrammar := nil;
|
||||
fGrammarFile := pFile;
|
||||
fErrorHandler := pErrorHandler;
|
||||
|
||||
fWarningCount := 0;
|
||||
fErrorCount := 0;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TTool.Create( pModuleStream : TStream;
|
||||
pModuleName : AnsiString;
|
||||
pOutputDir : AnsiString;
|
||||
pExchangeDir : AnsiString;
|
||||
pErrorHandler : IToolErrorHandler);
|
||||
begin
|
||||
fGrammar := nil;
|
||||
fWarningCount := 0;
|
||||
fErrorCount := 0;
|
||||
|
||||
fModuleStream := pModuleStream;
|
||||
fModuleName := pModuleName;
|
||||
fOutputDir := pOutputDir;
|
||||
fExchangeDir := pExchangeDir;
|
||||
fErrorHandler := pErrorHandler;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TTool.Destroy;
|
||||
begin
|
||||
fGrammar := nil;
|
||||
fErrorHandler := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
//
|
||||
// ITool implementation
|
||||
//
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Go
|
||||
// ============================================================================
|
||||
procedure TTool.Go;
|
||||
var
|
||||
parser : TDpgParser;
|
||||
lexer : TDpgLexer;
|
||||
|
||||
gmaker : IGrammarBehavior;
|
||||
analyzer : ILLkAnalyzer;
|
||||
gen : ICodeGenerator;
|
||||
|
||||
begin
|
||||
fWarningCount := 0;
|
||||
fErrorCount := 0;
|
||||
|
||||
if (fModuleStream <> nil) and (fModuleName <> '') then
|
||||
begin
|
||||
try
|
||||
analyzer := TLLkAnalyzer .Create( self);
|
||||
gmaker := TGrammarMaker .Create( self, analyzer, fExchangeDir);
|
||||
gen := TDelphiGenerator .Create( fOutputDir, fExchangeDir);
|
||||
|
||||
lexer := TDpgLexer .Create( fModuleStream);
|
||||
parser := TDpgParser .Create( lexer, gmaker, self, fExchangeDir);
|
||||
|
||||
lexer.InputState.FileName := fModuleName;
|
||||
parser.InputState.FileName := fModuleName;
|
||||
|
||||
except
|
||||
if fErrorHandler <> nil then
|
||||
fErrorHandler.Error('Internal error');
|
||||
exit;
|
||||
end;
|
||||
|
||||
try
|
||||
parser.grammar;
|
||||
|
||||
except
|
||||
on mc: EMismatchedChar do begin exMismatchedChar( mc); exit; end;
|
||||
on mt: EMismatchedToken do begin exMismatchedToken(mt); exit; end;
|
||||
else
|
||||
begin
|
||||
if fErrorHandler <> nil then
|
||||
fErrorHandler.Error('Error: Unexpected exception...');
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
if fErrorCount = 0 then
|
||||
begin
|
||||
fGrammar := gmaker.Grammar;
|
||||
|
||||
try
|
||||
gen.Gen( gmaker.Grammar);
|
||||
|
||||
except
|
||||
if fErrorHandler <> nil then
|
||||
fErrorHandler.Error('Unexpected exception in generator');
|
||||
end;
|
||||
end
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Get_ErrorHandler
|
||||
// ============================================================================
|
||||
function TTool.Get_ErrorHandler: IToolErrorHandler;
|
||||
begin
|
||||
result := nil;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Error
|
||||
// ============================================================================
|
||||
procedure TTool.Error( pMessage : AnsiString;
|
||||
pFileName: AnsiString;
|
||||
pLine : integer;
|
||||
pColumn : integer);
|
||||
var
|
||||
msg: AnsiString;
|
||||
|
||||
begin
|
||||
INC(fErrorCount);
|
||||
|
||||
if pColumn > 0
|
||||
then msg := pFileName +'(' +IntToStr(pLine) +',' +IntToStr(pColumn) +'): ' + pMessage
|
||||
else msg := pFileName +'(' +IntToStr(pLine) +'): ' + pMessage;
|
||||
|
||||
if fErrorHandler <> nil then
|
||||
fErrorHandler.Error( msg, pFileName, pLine, pColumn);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Warning
|
||||
// ============================================================================
|
||||
procedure TTool.Warning( pMessage : AnsiString;
|
||||
pFileName: AnsiString;
|
||||
pLine : integer;
|
||||
pColumn : integer);
|
||||
var
|
||||
msg: AnsiString;
|
||||
|
||||
begin
|
||||
INC(fWarningCount);
|
||||
|
||||
msg := pFileName + '(' + IntToStr( pLine) + '): ' + pMessage;
|
||||
if fErrorHandler <> nil then
|
||||
fErrorHandler.Warning( msg, pFileName, pLine, pColumn);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Panic
|
||||
// ============================================================================
|
||||
procedure TTool.Panic( pMessage : AnsiString);
|
||||
var
|
||||
msg: AnsiString;
|
||||
|
||||
begin
|
||||
msg := pMessage;
|
||||
if fErrorHandler <> nil then
|
||||
fErrorHandler.Panic( msg);
|
||||
|
||||
// Raise EPanic.Create(msg);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// dumpSets
|
||||
// ============================================================================
|
||||
procedure TTool.dumpSets( pGrammar : IGrammar;
|
||||
pLexical : boolean;
|
||||
pSets : TInterfaceList;
|
||||
pDepth : integer);
|
||||
var
|
||||
i : integer;
|
||||
msg : AnsiString;
|
||||
la : ILookahead;
|
||||
|
||||
begin
|
||||
for i:=0 to pDepth-1 do
|
||||
begin
|
||||
la := pSets[i] as ILookahead;
|
||||
msg := Format(' k=%d ', [i+1]);
|
||||
|
||||
if la.LaSet = [] then
|
||||
msg := msg + '<EPS>'
|
||||
|
||||
else
|
||||
if pLexical
|
||||
then msg := msg + CharSetToStr( la.LaSet)
|
||||
else msg := msg + TokenSetToStr( la.LaSet, fGrammar.TokenManager);
|
||||
|
||||
fErrorHandler.Warning( msg);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// WarnAltAmbiguity
|
||||
// ============================================================================
|
||||
procedure TTool.WarnAltAmbiguity( pGrammar : IGrammar;
|
||||
pBlock : IAlternativeBlock;
|
||||
pLexical : boolean;
|
||||
pDepth : integer;
|
||||
pSets : TInterfaceList;
|
||||
pAltIdx1 : integer;
|
||||
pAltIdx2 : integer);
|
||||
var
|
||||
rb: IRuleBlock;
|
||||
msg: AnsiString;
|
||||
ai : IAlternative;
|
||||
aj : IAlternative;
|
||||
rri : IRuleRefElem;
|
||||
rrj : IRuleRefElem;
|
||||
ri : AnsiString;
|
||||
rj : AnsiString;
|
||||
|
||||
begin
|
||||
if fErrorHandler = nil then
|
||||
exit;
|
||||
|
||||
pBlock.QueryInterface(IRuleBlock, rb);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// prepare locals
|
||||
// ---------------------------------------------------------------
|
||||
ai := pBlock.Alternative[pAltIdx1];
|
||||
aj := pBlock.Alternative[pAltIdx2];
|
||||
|
||||
ai.Head.QueryInterface(IRuleRefElem, rri);
|
||||
aj.Head.QueryInterface(IRuleRefElem, rrj);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Handle ambiguity of rules.
|
||||
// ---------------------------------------------------------------
|
||||
if (rb <> nil) and
|
||||
(rri <> nil) and
|
||||
(rrj <> nil) and
|
||||
(pLexical) and
|
||||
pBlock.AutoGen then
|
||||
begin
|
||||
ri := TCodeGenerator.decodeLexerRuleName( rri.TargetRule);
|
||||
rj := TCodeGenerator.decodeLexerRuleName( rrj.TargetRule);
|
||||
msg := fGrammarFile +'(1): ';
|
||||
|
||||
fErrorHandler.Warning('');
|
||||
msg := msg + 'Lexical nondeterminism between rules "' +
|
||||
ri + '" and "' + rj + '"';// upon:';
|
||||
|
||||
fErrorHandler.Warning( msg);
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Handle ambiguity of alternatives.
|
||||
// ---------------------------------------------------------------
|
||||
else
|
||||
begin
|
||||
|
||||
fErrorHandler.Warning('');
|
||||
msg := pGrammar.GrammarFile (*fGrammarFile*) + '(' +
|
||||
IntToStr( pBlock.Line) + '): ';
|
||||
|
||||
if pLexical then
|
||||
msg := msg + 'lexical ';
|
||||
|
||||
msg := msg + 'nondeterminism between alts ' +
|
||||
IntToStr( pAltIdx1+1) + ' and ' + IntToStr( pAltIdx2+1) +
|
||||
' of block in rule "' + pBlock.EnclosingRule + '"';// upon:';
|
||||
|
||||
fErrorHandler.Warning( msg);
|
||||
end;
|
||||
|
||||
dumpSets( pGrammar, pLexical, pSets, pDepth);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// WarnAltExitAmbiguity
|
||||
// ============================================================================
|
||||
procedure TTool.WarnAltExitAmbiguity( pGrammar : IGrammar;
|
||||
pBlock : IBlockWithImpliedExitPath;
|
||||
pLexical : boolean;
|
||||
pDepth : integer;
|
||||
pSets : TInterfaceList;
|
||||
pAltIdx : integer);
|
||||
var
|
||||
fileline : AnsiString;
|
||||
msg : AnsiString;
|
||||
|
||||
begin
|
||||
if fErrorHandler <> nil then
|
||||
begin
|
||||
fileline := fGrammarFile + '(' + IntToStr( pBlock.Line) + '):';
|
||||
|
||||
msg := fileline;
|
||||
|
||||
if pLexical then
|
||||
msg := msg + 'lexical';
|
||||
|
||||
msg := msg +' nondeterminism between alt ' + IntToStr( pAltIdx) +
|
||||
' and exit branch of block in rule ' + pBlock.EnclosingRule + '.';
|
||||
|
||||
fErrorHandler.Warning('');
|
||||
fErrorHandler.Warning(msg);
|
||||
dumpSets( pGrammar, pLexical, pSets, pDepth);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Debug
|
||||
// ============================================================================
|
||||
procedure TTool.Debug(pMessage: AnsiString);
|
||||
begin
|
||||
if fErrorHandler <> nil then
|
||||
fErrorHandler.Error(pMessage);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// exMismatchedChar
|
||||
//
|
||||
// Handle lexer mismatched char exception.
|
||||
// ============================================================================
|
||||
procedure TTool.exMismatchedChar(mc: EMismatchedChar);
|
||||
var
|
||||
msg : AnsiString;
|
||||
filename : AnsiString;
|
||||
begin
|
||||
fileName := ExtractFileName(mc.FileName);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Handle AnsiString
|
||||
// ---------------------------------------------------------------
|
||||
if mc.FoundString <> '' then
|
||||
msg := 'Unexpected AnsiString token: ' + mc.FoundString
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Handle char
|
||||
// ---------------------------------------------------------------
|
||||
else
|
||||
begin
|
||||
if not mc.Inverted then
|
||||
msg := 'Expecting [' + CharSetToStr( mc.CharSet) + '] but found ' +
|
||||
CharSetToStr([mc.FoundChar])
|
||||
else
|
||||
msg := 'Not expecting [' + CharSetToStr( mc.CharSet) + '] and found ' +
|
||||
CharSetToStr([mc.FoundChar])
|
||||
end;
|
||||
|
||||
Error( msg, fileName, mc.Line, mc.Column);
|
||||
(*
|
||||
// ---------------------------------------------------------------
|
||||
// Unexpected AnsiString, AnsiString
|
||||
// ---------------------------------------------------------------
|
||||
if mc.ExpCode = EC_CHAR then
|
||||
msg := 'Unexpected token: ' + CharSetToStr([mc.FoundChar])
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Unexpected char, charset
|
||||
// ---------------------------------------------------------------
|
||||
else if mc.ExpCode = EC_CHARSET then
|
||||
if not mc.Invert then
|
||||
msg := 'Expecting [' + CharSetToStr( mc.CharSet) + '] but found ' +
|
||||
CharSetToStr([mc.FoundChar])
|
||||
else
|
||||
msg := 'Not expecting [' + CharSetToStr( mc.CharSet) + '] and found ' +
|
||||
CharSetToStr([mc.FoundChar])
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Unexpected char, char range
|
||||
// ---------------------------------------------------------------
|
||||
else if mc.ExpCode = EC_CHARRANGE then
|
||||
if not mc.Invert then
|
||||
msg := 'Expecting [' + CharSetToStr( mc.CharSet) + '] but found ' +
|
||||
CharSetToStr([mc.FoundChar])
|
||||
else
|
||||
msg := 'Not expecting [' + CharSetToStr( mc.CharSet) + '] and found ' +
|
||||
CharSetToStr([mc.FoundChar])
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Unexpected AnsiString
|
||||
// ---------------------------------------------------------------
|
||||
else if mc.ExpCode = EC_STRING then
|
||||
msg := 'Unexpected AnsiString token: ' + mc.FoundStr
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Something wrong...
|
||||
// ---------------------------------------------------------------
|
||||
else
|
||||
msg := 'Internal error: Unknown lexer exception.';
|
||||
|
||||
Error( msg, fileName, mc.Line, mc.Column);
|
||||
*)
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// exMismatchedToken
|
||||
//
|
||||
// Handle parser mismatched token exception.
|
||||
//
|
||||
// Note: the member fGrammar now valid at this point, so we can use the
|
||||
// grammar's token manager.
|
||||
// ============================================================================
|
||||
procedure TTool.exMismatchedToken(mt: EMismatchedToken);
|
||||
var
|
||||
fileName : string;
|
||||
msg : string;
|
||||
|
||||
begin
|
||||
fileName := ExtractFileName( mt.FileName);
|
||||
msg := 'Unexpected token: ' + mt.FoundToken.TokenText;
|
||||
|
||||
Error( msg, fileName, mt.Line, mt.Column);
|
||||
end;
|
||||
|
||||
|
||||
function TTool.GetErrorCount: integer;
|
||||
begin
|
||||
result := fErrorCount;
|
||||
end;
|
||||
|
||||
function TTool.GetWarningCount: integer;
|
||||
begin
|
||||
result := fWarningCount;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,63 @@
|
||||
// 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.
|
||||
@@ -0,0 +1,145 @@
|
||||
// A TreeElement is a block with one alternative and a root node
|
||||
unit dpglib.TreeElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.AlternativeBlock;
|
||||
|
||||
type
|
||||
TTreeElem = class( TAlternativeBlock,
|
||||
ITreeElem,
|
||||
IGrammarElem)
|
||||
|
||||
protected
|
||||
fRoot : IGrammarAtom;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// ITreeElem
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function GetRoot: IGrammarAtom;
|
||||
procedure SetRoot( pRoot: IGrammarAtom);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
|
||||
public
|
||||
constructor Create( Grammar : IGrammar;
|
||||
Start : IToken;
|
||||
Invert : boolean);
|
||||
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TTreeElem }
|
||||
|
||||
|
||||
|
||||
// @@@: Construction / destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction / destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TTreeElem.Create(Grammar: IGrammar; Start: IToken; Invert: boolean);
|
||||
begin
|
||||
inherited
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// @@@: ITreeElem implementation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// ITreeElem implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Root
|
||||
// ================================================================================================
|
||||
function TTreeElem.GetRoot: IGrammarAtom;
|
||||
begin
|
||||
result := fRoot
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Root
|
||||
// ================================================================================================
|
||||
procedure TTreeElem.SetRoot(pRoot: IGrammarAtom);
|
||||
begin
|
||||
fRoot := pRoot
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// @@@: IGrammarElem overrides ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IGrammarElem overrides
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Look
|
||||
// ================================================================================================
|
||||
function TTreeElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Generate
|
||||
// ================================================================================================
|
||||
procedure TTreeElem.Generate;
|
||||
begin
|
||||
fGrammar.Generator.Gen( self);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// As String
|
||||
// ================================================================================================
|
||||
function TTreeElem.AsString: AnsiString;
|
||||
var
|
||||
alt : IAlternative;
|
||||
elem : IAlternativeElem;
|
||||
|
||||
begin
|
||||
result := ' #(';
|
||||
|
||||
if Assigned(fRoot) then
|
||||
result := result +fRoot.AsString;
|
||||
|
||||
alt := fAlternatives.Items[0] as IAlternative;
|
||||
elem := alt.Head;
|
||||
|
||||
while Assigned(elem) do
|
||||
begin
|
||||
result := result + elem.AsString;
|
||||
elem := elem.Next;
|
||||
end;
|
||||
|
||||
result := result +')';
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,22 @@
|
||||
unit dpglib.TreeParserGrammar;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.Contnrs,
|
||||
dpgrtl.types,
|
||||
dpglib.Types,
|
||||
dpglib.ParserGrammar;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TParserGrammar
|
||||
// =========================================================================
|
||||
TTreeParserGrammar = class(TParserGrammar,
|
||||
IGrammar,
|
||||
ITreeWalkerGrammar)
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,622 @@
|
||||
unit dpglib.utils;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
Generics.Collections,
|
||||
dpgrtl.types,
|
||||
dpglib.types;
|
||||
|
||||
type
|
||||
cType = (ctOther, ctNumber, ctAlpha, ctAlnum, ctPrint);
|
||||
sType = set of cType;
|
||||
|
||||
TCharFormater = function ( c: char): AnsiString;
|
||||
|
||||
function IsNumber( c: AnsiChar): boolean;
|
||||
function IsAlpha( c: AnsiChar): boolean;
|
||||
function IsAlnum( c: AnsiChar): boolean;
|
||||
function IsPrint( c: AnsiChar): boolean;
|
||||
|
||||
function StringToID( s: AnsiString): AnsiString;
|
||||
|
||||
|
||||
function DelphiCharFormater( c : AnsiChar) : AnsiString;
|
||||
|
||||
|
||||
function DelphiTokenFormater( t : integer;
|
||||
tm : ITokenManager = nil) : AnsiString;
|
||||
|
||||
function TokenSetToStr( pBS : TByteSet;
|
||||
pTM : ITokenManager = nil): AnsiString;
|
||||
|
||||
{
|
||||
function DelphiTokenFormater( t : integer;
|
||||
v : TStringList = nil) : AnsiString;
|
||||
|
||||
function TokenSetToStr( pBS : TByteSet;
|
||||
pVocab: TStringList = nil): AnsiString;
|
||||
}
|
||||
|
||||
function CharSetToStr( pBS : TCharSet;
|
||||
pFmt : TCharFormater= nil): AnsiString; overload;
|
||||
|
||||
function CharSetToStr( pBS : TByteSet;
|
||||
pFmt : TCharFormater= nil): AnsiString; overload;
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.StrUtils;
|
||||
|
||||
var
|
||||
c : AnsiChar;
|
||||
cTable: array [AnsiChar] of sType;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetStringOfToken
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
function GetStringOfToken( t: integer; v: TStringList): AnsiString;
|
||||
var
|
||||
i : integer;
|
||||
p : integer;
|
||||
name : AnsiString;
|
||||
value : AnsiString;
|
||||
str : AnsiString;
|
||||
begin
|
||||
result := '';
|
||||
|
||||
for i:=0 to v.Count-1 do
|
||||
begin
|
||||
name := v.Names[i];
|
||||
value := v.ValueFromIndex[i];
|
||||
|
||||
if StrToIntDef( value,-1) = t then
|
||||
begin
|
||||
if name[1] = '"' then
|
||||
begin
|
||||
name := Copy(name,2,Length(name)-2);
|
||||
result := 'LT_' + name;
|
||||
|
||||
result := AnsiReplaceText( result, '$', '_DOLLAR_');
|
||||
result := AnsiReplaceText( result, '/', '_SLASH_');
|
||||
result := AnsiReplaceText( result, ':', '_COLON_');
|
||||
result := AnsiReplaceText( result, '.', '_DOT_');
|
||||
|
||||
result := AnsiReplaceText( result, 'LT__', 'LT_');
|
||||
|
||||
break;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
result := 'TT_' + name;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetStringOfToken
|
||||
// ----------------------------------------------------------------------------
|
||||
function GetStringOfToken( t: integer; tm: ITokenManager): AnsiString;
|
||||
var
|
||||
ts : ITokenSymbol;
|
||||
ss : IStringSymbol;
|
||||
|
||||
begin
|
||||
result := '';
|
||||
ts := tm.TokenSymbolByType[t];
|
||||
|
||||
if Assigned(ts) then
|
||||
begin
|
||||
ts.QueryInterface( IStringSymbol, ss);
|
||||
|
||||
if Assigned(ss) then
|
||||
begin
|
||||
if ss.Lbl <> ''
|
||||
then result := ss.Lbl
|
||||
else result := 'LT_'+ss.ID;
|
||||
|
||||
result := AnsiString( AnsiReplaceText( String(result), '#', '_SHARP_'));
|
||||
result := AnsiString( AnsiReplaceText( String(result), '*', '_STAR_'));
|
||||
result := AnsiString( AnsiReplaceText( String(result), '$', '_DOLLAR_'));
|
||||
result := AnsiString( AnsiReplaceText( String(result), '/', '_SLASH_'));
|
||||
result := AnsiString( AnsiReplaceText( String(result), ':', '_COLON_'));
|
||||
result := AnsiString( AnsiReplaceText( String(result), '.', '_DOT_'));
|
||||
|
||||
result := AnsiString( AnsiReplaceText( String(result), 'LT__', 'LT_'));
|
||||
end
|
||||
|
||||
else
|
||||
result := 'TT_' +ts.ID;
|
||||
end
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// DelphiCharFormater
|
||||
// ----------------------------------------------------------------------------
|
||||
function DelphiCharFormater( c: AnsiChar): AnsiString;
|
||||
var
|
||||
tmp: string;
|
||||
|
||||
begin
|
||||
if isPrint( c) then
|
||||
if c = '''' then
|
||||
tmp := ''''''''''
|
||||
else
|
||||
tmp := '''' + c + ''''
|
||||
else
|
||||
tmp := '#' + IntToStr( ord(c));
|
||||
|
||||
result := AnsiString( tmp);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// DelphiTokenFormater
|
||||
// ----------------------------------------------------------------------------
|
||||
function DelphiTokenFormater( t: integer; tm: ITokenManager): AnsiString;
|
||||
begin
|
||||
if tm <> nil then
|
||||
result := GetStringOfToken( t, tm);
|
||||
|
||||
if result = '' then
|
||||
result := AnsiString( 'TT_' + Format('%3.3d',[t]));
|
||||
end;
|
||||
{
|
||||
function DelphiTokenFormater( t: integer; v: TStringList): AnsiString;
|
||||
begin
|
||||
if v <> nil then
|
||||
result := GetStringOfToken( t, v);
|
||||
|
||||
if result = '' then
|
||||
result := 'TT_' + Format('%3.3d',[t]);
|
||||
end;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// TokenSetToStr
|
||||
// ----------------------------------------------------------------------------
|
||||
function TokenSetToStr( pBS : TByteSet;
|
||||
pTM : ITokenManager): AnsiString;
|
||||
var
|
||||
t : integer;
|
||||
firstToken : integer;
|
||||
lastToken : integer;
|
||||
|
||||
begin
|
||||
result := '';
|
||||
t := 0;
|
||||
|
||||
while t <= 255 do
|
||||
begin
|
||||
// ------------------------------------------------------------
|
||||
// Find the first "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
while (not (t in pBS)) and (t <= 255) do
|
||||
INC(t);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Check that we are reached the end
|
||||
// ------------------------------------------------------------
|
||||
if t = 256 then
|
||||
break;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// OK, we found the first "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
firstToken := t;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Fin the last "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
while (t in pBS) and (t <= 255) do
|
||||
INC(t);
|
||||
|
||||
lastToken := pred(t);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Append "," to the result if this founded range is not the
|
||||
// first in the result.
|
||||
// ------------------------------------------------------------
|
||||
if result <> '' then
|
||||
result := result + ',';
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Build the first "bit" into the result
|
||||
// ------------------------------------------------------------
|
||||
result := result + DelphiTokenFormater( firstToken, pTM);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Build range if the firstChar not equals to the lastChar
|
||||
// ------------------------------------------------------------
|
||||
if firstToken <> lastToken then
|
||||
result := result + '..' + DelphiTokenFormater( lastToken, pTM);
|
||||
end;
|
||||
end;
|
||||
|
||||
{
|
||||
function TokenSetToStr( pBS : TByteSet;
|
||||
pVocab: TStringList): AnsiString;
|
||||
var
|
||||
t : integer;
|
||||
firstToken : integer;
|
||||
lastToken : integer;
|
||||
|
||||
begin
|
||||
result := '';
|
||||
t := 0;
|
||||
|
||||
while t <= 255 do
|
||||
begin
|
||||
// ------------------------------------------------------------
|
||||
// Find the first "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
while (not (t in pBS)) and (t <= 255) do
|
||||
INC(t);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Check that we are reached the end
|
||||
// ------------------------------------------------------------
|
||||
if t = 256 then
|
||||
break;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// OK, we found the first "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
firstToken := t;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Fin the last "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
while (t in pBS) and (t <= 255) do
|
||||
INC(t);
|
||||
|
||||
lastToken := pred(t);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Append "," to the result if this founded range is not the
|
||||
// first in the result.
|
||||
// ------------------------------------------------------------
|
||||
if result <> '' then
|
||||
result := result + ',';
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Build the first "bit" into the result
|
||||
// ------------------------------------------------------------
|
||||
result := result + DelphiTokenFormater( firstToken, pVocab);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Build range if the firstChar not equals to the lastChar
|
||||
// ------------------------------------------------------------
|
||||
if firstToken <> lastToken then
|
||||
result := result + '..' + DelphiTokenFormater( lastToken, pVocab);
|
||||
end;
|
||||
end;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CharSetToStr
|
||||
// ----------------------------------------------------------------------------
|
||||
function CharSetToStr( pBS : TCharSet;
|
||||
pFmt : TCharFormater): AnsiString;
|
||||
var
|
||||
c : integer;
|
||||
firstChar: AnsiChar;
|
||||
lastChar : AnsiChar;
|
||||
|
||||
begin
|
||||
result := '';
|
||||
c := 0;
|
||||
|
||||
while c <= 255 do
|
||||
begin
|
||||
// ------------------------------------------------------------
|
||||
// Find the first "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
while (not (AnsiChar(c) in pBS)) and (c <= 255) do
|
||||
INC(c);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Check that we are reached the end
|
||||
// ------------------------------------------------------------
|
||||
if c = 256 then
|
||||
break;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// OK, we found the first "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
firstChar := AnsiChar(c);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Find the last "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
while (AnsiChar(c) in pBS) and (c <= 255) do
|
||||
INC(c);
|
||||
|
||||
lastChar := pred(AnsiChar(c));
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Append "," to the result if this founded range is not the
|
||||
// first in the result.
|
||||
// ------------------------------------------------------------
|
||||
if result <> '' then
|
||||
result := result + ',';
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Build the first "bit" into the result
|
||||
// ------------------------------------------------------------
|
||||
result := result + DelphiCharFormater( firstChar);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Build range if the firstChar not equals to the lastChar
|
||||
// ------------------------------------------------------------
|
||||
if firstChar <> lastChar then
|
||||
result := result + '..' + DelphiCharFormater( lastChar);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CharSetToStr
|
||||
// ----------------------------------------------------------------------------
|
||||
function CharSetToStr( pBS : TByteSet;
|
||||
pFmt : TCharFormater): AnsiString;
|
||||
var
|
||||
c : integer;
|
||||
firstChar: AnsiChar;
|
||||
lastChar : AnsiChar;
|
||||
|
||||
begin
|
||||
result := '';
|
||||
c := 0;
|
||||
|
||||
while c <= 255 do
|
||||
begin
|
||||
// ------------------------------------------------------------
|
||||
// Find the first "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
while (not (c in pBS)) and (c <= 255) do
|
||||
INC(c);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Check that we are reached the end
|
||||
// ------------------------------------------------------------
|
||||
if c = 256 then
|
||||
break;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// OK, we found the first "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
firstChar := AnsiChar(c);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Fin the last "bit" of the range
|
||||
// ------------------------------------------------------------
|
||||
while (c in pBS) and (c <= 255) do
|
||||
INC(c);
|
||||
|
||||
lastChar := AnsiChar(pred(c));
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Append "," to the result if this founded range is not the
|
||||
// first in the result.
|
||||
// ------------------------------------------------------------
|
||||
if result <> '' then
|
||||
result := result + ',';
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Build the first "bit" into the result
|
||||
// ------------------------------------------------------------
|
||||
result := result + DelphiCharFormater( firstChar);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Build range if the firstChar not equals to the lastChar
|
||||
// ------------------------------------------------------------
|
||||
if firstChar <> lastChar then
|
||||
result := result + '..' + DelphiCharFormater( lastChar);
|
||||
end;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsNumber
|
||||
// ----------------------------------------------------------------------------
|
||||
function IsNumber( c: AnsiChar): boolean;
|
||||
begin
|
||||
result := ctNumber in cTable[c];
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsAlpha
|
||||
// ----------------------------------------------------------------------------
|
||||
function IsAlpha( c: AnsiChar): boolean;
|
||||
begin
|
||||
result := ctAlpha in cTable[c];
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsAlnum
|
||||
// ----------------------------------------------------------------------------
|
||||
function IsAlnum( c: AnsiChar): boolean;
|
||||
begin
|
||||
result := ctAlnum in cTable[c];
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsPrint
|
||||
// ----------------------------------------------------------------------------
|
||||
function IsPrint( c: AnsiChar): boolean;
|
||||
begin
|
||||
result := ctPrint in cTable[c];
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Convert string to a valid identifier name
|
||||
// ================================================================================================
|
||||
function StringToID( s: AnsiString): AnsiString;
|
||||
var
|
||||
i: integer;
|
||||
c: AnsiChar;
|
||||
|
||||
begin
|
||||
result := '';
|
||||
|
||||
for c in s do
|
||||
begin
|
||||
if IsAlnum(c) then
|
||||
result := result +c
|
||||
|
||||
else if IsPrint(c) then
|
||||
case c of
|
||||
' ' : result := result + '_SPACE_';
|
||||
'!' : result := result + '_EXCL_';
|
||||
'#' : result := result + '_SHARP_';
|
||||
'$' : result := result + '_DOLLAR_';
|
||||
'§' : result := result + '_PARA_';
|
||||
'%' : result := result + '_PERCENT_';
|
||||
'&' : result := result + '_AND_';
|
||||
'''' : result := result + '_APOSTROPHE_';
|
||||
'(' : result := result + '_LPAREN_';
|
||||
')' : result := result + '_RPAREN_';
|
||||
'*' : result := result + '_STAR_';
|
||||
'+' : result := result + '_PLUS_';
|
||||
',' : result := result + '_COMMA_';
|
||||
'-' : result := result + '_MINUS_';
|
||||
'.' : result := result + '_DOT_';
|
||||
'/' : result := result + '_SLASH_';
|
||||
|
||||
':' : result := result + '_COLON_';
|
||||
';' : result := result + '_SEMI_';
|
||||
'<' : result := result + '_LT_';
|
||||
'=' : result := result + '_EQ_';
|
||||
'>' : result := result + '_GT_';
|
||||
'?' : result := result + '_QUESTION_';
|
||||
'@' : result := result + '_AT_';
|
||||
|
||||
'[' : result := result + '_LBRACKET_';
|
||||
'\' : result := result + '_BS_';
|
||||
']' : result := result + '_RBRACKET_';
|
||||
'^' : result := result + '_CARET_';
|
||||
|
||||
'{' : result := result + '_LCURLY_';
|
||||
'|' : result := result + '_OR_';
|
||||
'}' : result := result + '_RCURLY_';
|
||||
'~' : result := result + '_TILDE_';
|
||||
else result := result + Format('_0x2.2%x_',[c]);
|
||||
end;
|
||||
end;
|
||||
|
||||
if (Length(result) > 0) and (RightStr( result, 1) = '_') then
|
||||
result := Copy( result, 1, Length(result)-1);
|
||||
end;
|
||||
// ****************************************************************************
|
||||
// Initialization/finalization
|
||||
// ****************************************************************************
|
||||
initialization
|
||||
for c:=#0 to #255 do
|
||||
cTable[c] := [ctOther];
|
||||
|
||||
cTable[ ' '] := [ctPrint];
|
||||
cTable[ '!'] := [ctPrint];
|
||||
cTable[ '"'] := [ctPrint];
|
||||
cTable[ '#'] := [ctPrint];
|
||||
cTable[ '$'] := [ctPrint];
|
||||
cTable[ '§'] := [ctPrint];
|
||||
cTable[ '%'] := [ctPrint];
|
||||
cTable[ '&'] := [ctPrint];
|
||||
cTable[ ''''] := [ctPrint];
|
||||
cTable[ '('] := [ctPrint];
|
||||
cTable[ ')'] := [ctPrint];
|
||||
cTable[ '*'] := [ctPrint];
|
||||
cTable[ '+'] := [ctPrint];
|
||||
cTable[ ','] := [ctPrint];
|
||||
cTable[ '-'] := [ctPrint];
|
||||
cTable[ '.'] := [ctPrint];
|
||||
cTable[ '/'] := [ctPrint];
|
||||
|
||||
cTable[ '0'] := [ctPrint, ctNumber, ctAlnum];
|
||||
cTable[ '1'] := [ctPrint, ctNumber, ctAlnum];
|
||||
cTable[ '2'] := [ctPrint, ctNumber, ctAlnum];
|
||||
cTable[ '3'] := [ctPrint, ctNumber, ctAlnum];
|
||||
cTable[ '4'] := [ctPrint, ctNumber, ctAlnum];
|
||||
cTable[ '5'] := [ctPrint, ctNumber, ctAlnum];
|
||||
cTable[ '6'] := [ctPrint, ctNumber, ctAlnum];
|
||||
cTable[ '7'] := [ctPrint, ctNumber, ctAlnum];
|
||||
cTable[ '8'] := [ctPrint, ctNumber, ctAlnum];
|
||||
cTable[ '9'] := [ctPrint, ctNumber, ctAlnum];
|
||||
|
||||
cTable[ ':'] := [ctPrint];
|
||||
cTable[ ';'] := [ctPrint];
|
||||
cTable[ '<'] := [ctPrint];
|
||||
cTable[ '='] := [ctPrint];
|
||||
cTable[ '>'] := [ctPrint];
|
||||
cTable[ '?'] := [ctPrint];
|
||||
cTable[ '@'] := [ctPrint];
|
||||
|
||||
cTable[ 'A'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'B'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'C'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'D'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'E'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'F'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'G'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'H'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'I'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'J'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'K'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'L'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'M'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'N'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'O'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'P'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'Q'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'R'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'S'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'T'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'U'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'V'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'W'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'X'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'Y'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'Z'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
|
||||
cTable[ '['] := [ctPrint];
|
||||
cTable[ '\'] := [ctPrint];
|
||||
cTable[ ']'] := [ctPrint];
|
||||
cTable[ '^'] := [ctPrint];
|
||||
cTable[ '_'] := [ctPrint];
|
||||
cTable[ '`'] := [ctPrint];
|
||||
|
||||
cTable[ 'a'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'b'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'c'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'd'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'e'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'f'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'g'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'h'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'i'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'j'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'k'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'l'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'm'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'n'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'o'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'p'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'q'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'r'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 's'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 't'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'u'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'v'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'w'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'x'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'y'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
cTable[ 'z'] := [ctPrint, ctAlpha, ctAlnum];
|
||||
|
||||
cTable[ '{'] := [ctPrint];
|
||||
cTable[ '|'] := [ctPrint];
|
||||
cTable[ '}'] := [ctPrint];
|
||||
cTable[ '~'] := [ctPrint];
|
||||
end.
|
||||
@@ -0,0 +1,9 @@
|
||||
unit dpglib.Version;
|
||||
|
||||
interface
|
||||
const
|
||||
version: string = '2.1.0.0r';
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,107 @@
|
||||
unit dpglib.WildCardElem;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.Types,
|
||||
dpglib.GrammarAtom;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TWildcardElem declaration
|
||||
// =========================================================================
|
||||
TWildcardElem = class( TGrammarAtom,
|
||||
IwildcardElem,
|
||||
IGrammarAtom,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Constructor/destructor
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
constructor Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pAutoGenType: integer);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString: AnsiString;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// IAlternativeElem overrides
|
||||
// ---------------------------------------------------------------
|
||||
protected
|
||||
function Get_Label : AnsiString;
|
||||
procedure Put_Label( pLabel: AnsiString);
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
// ****************************************************************************
|
||||
// Constructor/destructor
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TWildcardElem.Create( pGrammar : IGrammar;
|
||||
pToken : IToken;
|
||||
pAutoGenType: integer);
|
||||
begin
|
||||
inherited Create( pGrammar, pToken, pAutoGenType);
|
||||
fLine := pToken.TokenLine;
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IGrammarElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Generate
|
||||
// ============================================================================
|
||||
procedure TWildcardElem.Generate;
|
||||
begin
|
||||
fGrammar.Generator.gen( self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Look
|
||||
// ============================================================================
|
||||
function TWildcardElem.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self);
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// AsString
|
||||
// ============================================================================
|
||||
function TWildcardElem.AsString: AnsiString;
|
||||
begin
|
||||
result := '';
|
||||
if fLabel <> '' then result := result + fLabel + ':';
|
||||
result := result + '.';
|
||||
end;
|
||||
|
||||
// ****************************************************************************
|
||||
// IAlternativeElem overrides
|
||||
// ****************************************************************************
|
||||
// ============================================================================
|
||||
// Get_Label
|
||||
// ============================================================================
|
||||
function TWildcardElem.Get_Label: AnsiString;
|
||||
begin
|
||||
result := fLabel;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Put_Label
|
||||
// ============================================================================
|
||||
procedure TWildcardElem.Put_Label(pLabel: AnsiString);
|
||||
begin
|
||||
fLabel := pLabel;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,60 @@
|
||||
unit dpglib.ZeroOrMoreBlock;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpglib.types,
|
||||
dpglib.BlockWithImpliedExitPath;
|
||||
|
||||
type
|
||||
TZeroOrMoreBlock = class( TBlockWithImpliedExitPath,
|
||||
IZeroOrMoreBlock,
|
||||
IBlockWithImpliedExitPath,
|
||||
IAlternativeBlock,
|
||||
IAlternativeElem,
|
||||
IGrammarElem)
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IGrammarElem overrides
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
procedure Generate;
|
||||
function Look( pK: integer): ILookahead;
|
||||
function AsString : AnsiString;
|
||||
end;
|
||||
|
||||
implementation
|
||||
// @@@: IGrammarElem overrides ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IGrammarElem overrides
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Generate
|
||||
// ================================================================================================
|
||||
procedure TZeroOrMoreBlock.Generate;
|
||||
begin
|
||||
fGrammar.Generator.Gen( self);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Look
|
||||
// ================================================================================================
|
||||
function TZeroOrMoreBlock.Look(pK: integer): ILookahead;
|
||||
begin
|
||||
result := fGrammar.LLkAnalyzer.Look( pK, self)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// AsString
|
||||
// ================================================================================================
|
||||
function TZeroOrMoreBlock.AsString: AnsiString;
|
||||
begin
|
||||
result := inherited AsString + '*'
|
||||
end;
|
||||
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,356 @@
|
||||
unit dpglib.DpgLexer;
|
||||
|
||||
lexer TDpgLexer;
|
||||
options
|
||||
{
|
||||
testLiterals = false;
|
||||
k = 2;
|
||||
}
|
||||
|
||||
tokens
|
||||
{
|
||||
"unit";
|
||||
"uses";
|
||||
"const";
|
||||
"type";
|
||||
|
||||
"lexer";
|
||||
"parser";
|
||||
"treeparser";
|
||||
|
||||
"options";
|
||||
"tokens";
|
||||
"memberdecl";
|
||||
"memberdef";
|
||||
|
||||
"private";
|
||||
"protected";
|
||||
"public";
|
||||
|
||||
"returns";
|
||||
"local";
|
||||
|
||||
"except";
|
||||
"finally";
|
||||
|
||||
SEMPRED;
|
||||
|
||||
USES;
|
||||
OPTIONS;
|
||||
TOKENS;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Simple tokens
|
||||
// ----------------------------------------------------------------------------
|
||||
LPAREN: '(';
|
||||
RPAREN: ')';
|
||||
|
||||
RCURLY: '}';
|
||||
|
||||
COLON: ':';
|
||||
SEMI: ';';
|
||||
COMMA: ',';
|
||||
|
||||
ASSIGN: '=';
|
||||
IMPLIES: "=>";
|
||||
|
||||
QUEST: '?';
|
||||
PLUS: '+';
|
||||
STAR: '*';
|
||||
AT: '@';
|
||||
|
||||
NOT: '~';
|
||||
OR: '|';
|
||||
BANG: '!';
|
||||
|
||||
WILDCARD: '.';
|
||||
RANGE: "..";
|
||||
|
||||
OPEN: '<';
|
||||
CLOSE: '>';
|
||||
CARET: '^';
|
||||
|
||||
TREE_BEGIN: "#(";
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Character literal
|
||||
// ----------------------------------------------------------------------------
|
||||
CHARLIT
|
||||
: '\''! (ESC | ~'\'') '\''! ;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// String literal
|
||||
// ----------------------------------------------------------------------------
|
||||
STRINGLIT
|
||||
: '"' (ESC | ~'"')* '"' ;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Integer
|
||||
// ----------------------------------------------------------------------------
|
||||
INTEGER
|
||||
local
|
||||
{
|
||||
i: integer;
|
||||
v: integer;
|
||||
}
|
||||
:
|
||||
(
|
||||
DNUMBER
|
||||
{
|
||||
v := 0;
|
||||
for i:=1 to Length( TokenText) do
|
||||
begin
|
||||
v := v * 10 + ord( TokenText[i]) - ord('0');
|
||||
end;
|
||||
|
||||
TokenText := IntToStr( v);
|
||||
}
|
||||
|
|
||||
XNUMBER
|
||||
{
|
||||
v := 0;
|
||||
for i:=1 to Length( TokenText) do
|
||||
begin
|
||||
case TokenText[i] of
|
||||
'0'..'9': v := v * 16 + ord(TokenText[i]) - ord('0');
|
||||
'a'..'z': v := v * 16 + ord(TokenText[i]) - ord('a');
|
||||
'A'..'Z': v := v * 16 + ord(TokenText[i]) - ord('A');
|
||||
end;
|
||||
end;
|
||||
|
||||
TokenText := IntToStr( v);
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Argument action
|
||||
// ----------------------------------------------------------------------------
|
||||
ARGACTION
|
||||
:
|
||||
'['!
|
||||
(
|
||||
options
|
||||
{
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
| ~']'
|
||||
)*
|
||||
']'!
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Action
|
||||
// ----------------------------------------------------------------------------
|
||||
ACTION
|
||||
:
|
||||
'{'
|
||||
(
|
||||
options
|
||||
{
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
| ~'}'
|
||||
)*
|
||||
'}'
|
||||
( '?'! { _ttype := TT_SEMPRED; } )?
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Token ref
|
||||
// ----------------------------------------------------------------------------
|
||||
TOKENREF
|
||||
options
|
||||
{
|
||||
testLiterals = true;
|
||||
}
|
||||
: 'A'..'Z' ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')* ;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rule ref
|
||||
// ----------------------------------------------------------------------------
|
||||
RULEREF
|
||||
local
|
||||
{
|
||||
t: integer;
|
||||
}
|
||||
:
|
||||
t = INT_RULEREF { _ttype := t; }
|
||||
(
|
||||
{t = LT_uses}? WS_LOOP ('{' { _ttype := TT_USES; } )?
|
||||
| {t = LT_options}? WS_LOOP ('{' { _ttype := TT_OPTIONS; } )?
|
||||
| {t = LT_tokens}? WS_LOOP ('{' { _ttype := TT_TOKENS; } )?
|
||||
)?
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Internal rule ref
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
INT_RULEREF returns [integer]
|
||||
{
|
||||
_ttype := TT_RULEREF;
|
||||
}
|
||||
: 'a'..'z' ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
|
||||
{
|
||||
result := TestLiteral( _ttype);
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// COMMENT
|
||||
// ----------------------------------------------------------------------------
|
||||
COMMENT
|
||||
: SLCOMMENT { _ttype := TT_SKIP; }
|
||||
| MLCOMMENT1 { _ttype := TT_SKIP; }
|
||||
| MLCOMMENT2 { _ttype := TT_SKIP; }
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SLCOMMENT
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
SLCOMMENT
|
||||
:
|
||||
"//"
|
||||
( ~( '\r' | '\n') )*
|
||||
(
|
||||
options
|
||||
{
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
)
|
||||
;
|
||||
|
||||
// ============================================================================
|
||||
// Multi line comment version 1
|
||||
// Nested comments aren't allowed!
|
||||
// ============================================================================
|
||||
protected
|
||||
MLCOMMENT1
|
||||
:
|
||||
"(*"
|
||||
(
|
||||
options
|
||||
{
|
||||
greedy = false;
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
| .
|
||||
)*
|
||||
"*)"
|
||||
;
|
||||
|
||||
// ============================================================================
|
||||
// Multi line comment version 2
|
||||
// Nested comments aren't allowed!
|
||||
// ============================================================================
|
||||
protected
|
||||
MLCOMMENT2
|
||||
:
|
||||
"/*"
|
||||
(
|
||||
options
|
||||
{
|
||||
greedy = false;
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
| .
|
||||
)*
|
||||
"*/"
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Numbers
|
||||
// ----------------------------------------------------------------------------
|
||||
protected DNUMBER: '0'..'9' (DDIGIT)*;
|
||||
protected XNUMBER: '$'! (XDIGIT)+;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Digits
|
||||
// ----------------------------------------------------------------------------
|
||||
protected DDIGIT: '0'..'9';
|
||||
protected XDIGIT: '0'..'9' | 'a'..'f' | 'A'..'F';
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WS
|
||||
// ----------------------------------------------------------------------------
|
||||
WS
|
||||
:
|
||||
(
|
||||
options
|
||||
{
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: ' '
|
||||
| '\t' { tab; }
|
||||
| '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
)
|
||||
{
|
||||
_ttype := TT_SKIP;
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WS_LOOP
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
WS_LOOP
|
||||
:
|
||||
(
|
||||
options
|
||||
{
|
||||
greedy = true;
|
||||
}
|
||||
: WS
|
||||
| COMMENT
|
||||
)*
|
||||
;
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Esc
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
ESC
|
||||
local
|
||||
{
|
||||
number: AnsiString;
|
||||
}
|
||||
:
|
||||
'\\'!
|
||||
(
|
||||
'r' { TokenText[ Length( TokenText)] := AnsiChar(13); }
|
||||
| 'n' { TokenText[ Length( TokenText)] := AnsiChar(10); }
|
||||
| 't' { TokenText[ Length( TokenText)] := AnsiChar(9); }
|
||||
| '\\'
|
||||
| '\''
|
||||
| '"'
|
||||
| 'x' d1:XDIGIT! d2:XDIGIT!
|
||||
{
|
||||
number := '$' + d1.TokenText + d2.TokenText;
|
||||
TokenText[ Length( TokenText)] := AnsiChar( StrToInt( number));
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,77 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.1.0.0r
|
||||
// Grammar: dpglib.dpgLexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.DpgLexerTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_TREE_BEGIN = 46;
|
||||
LT_finally = 21;
|
||||
TT_QUEST = 34;
|
||||
TT_INT_RULEREF = 54;
|
||||
TT_IMPLIES = 33;
|
||||
LT_returns = 18;
|
||||
TT_WILDCARD = 41;
|
||||
TT_OR = 39;
|
||||
TT_CLOSE = 44;
|
||||
TT_WS = 63;
|
||||
LT_public = 17;
|
||||
TT_RCURLY = 28;
|
||||
TT_COMMA = 31;
|
||||
LT_parser = 9;
|
||||
LT_unit = 4;
|
||||
TT_CHARLIT = 47;
|
||||
LT_tokens = 12;
|
||||
LT_uses = 5;
|
||||
TT_SEMI = 30;
|
||||
TT_ASSIGN = 32;
|
||||
TT_OPEN = 43;
|
||||
LT_treeparser = 10;
|
||||
LT_memberdecl = 13;
|
||||
TT_OPTIONS = 24;
|
||||
TT_AT = 37;
|
||||
LT_local = 19;
|
||||
TT_SEMPRED = 22;
|
||||
TT_CARET = 45;
|
||||
TT_MLCOMMENT2 = 58;
|
||||
TT_DDIGIT = 61;
|
||||
LT_lexer = 8;
|
||||
LT_memberdef = 14;
|
||||
TT_RULEREF = 53;
|
||||
LT_except = 20;
|
||||
TT_COLON = 29;
|
||||
TT_EOF = 1;
|
||||
LT_protected = 16;
|
||||
TT_INTEGER = 49;
|
||||
TT_STAR = 36;
|
||||
TT_ACTION = 51;
|
||||
LT_type = 7;
|
||||
LT_private = 15;
|
||||
TT_LPAREN = 26;
|
||||
TT_RPAREN = 27;
|
||||
TT_BANG = 40;
|
||||
TT_MLCOMMENT1 = 57;
|
||||
TT_DNUMBER = 59;
|
||||
TT_TOKENS = 25;
|
||||
TT_ESC = 65;
|
||||
TT_USES = 23;
|
||||
TT_TOKENREF = 52;
|
||||
TT_NOT = 38;
|
||||
TT_SLCOMMENT = 56;
|
||||
TT_STRINGLIT = 48;
|
||||
TT_XDIGIT = 62;
|
||||
TT_WS_LOOP = 64;
|
||||
LT_options = 11;
|
||||
LT_const = 6;
|
||||
TT_ARGACTION = 50;
|
||||
TT_RANGE = 42;
|
||||
TT_PLUS = 35;
|
||||
TT_XNUMBER = 60;
|
||||
TT_COMMENT = 55;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,65 @@
|
||||
// $Delphi Parser Generator: dpglib.dpgLexer.g -> dpglib.dpgLexer.gTokens.txt$
|
||||
TDpgLexer
|
||||
TT_TREE_BEGIN=46
|
||||
LT_finally="finally"=21
|
||||
TT_QUEST=34
|
||||
TT_INT_RULEREF=54
|
||||
TT_IMPLIES=33
|
||||
LT_returns="returns"=18
|
||||
TT_WILDCARD=41
|
||||
TT_OR=39
|
||||
TT_CLOSE=44
|
||||
TT_WS=63
|
||||
LT_public="public"=17
|
||||
TT_RCURLY=28
|
||||
TT_COMMA=31
|
||||
LT_parser="parser"=9
|
||||
LT_unit="unit"=4
|
||||
TT_CHARLIT=47
|
||||
LT_tokens="tokens"=12
|
||||
LT_uses="uses"=5
|
||||
TT_SEMI=30
|
||||
TT_ASSIGN=32
|
||||
TT_OPEN=43
|
||||
LT_treeparser="treeparser"=10
|
||||
LT_memberdecl="memberdecl"=13
|
||||
TT_OPTIONS=24
|
||||
TT_AT=37
|
||||
LT_local="local"=19
|
||||
TT_SEMPRED=22
|
||||
TT_CARET=45
|
||||
TT_MLCOMMENT2=58
|
||||
TT_DDIGIT=61
|
||||
LT_lexer="lexer"=8
|
||||
LT_memberdef="memberdef"=14
|
||||
TT_RULEREF=53
|
||||
LT_except="except"=20
|
||||
TT_COLON=29
|
||||
TT_EOF=1
|
||||
LT_protected="protected"=16
|
||||
TT_INTEGER=49
|
||||
TT_STAR=36
|
||||
TT_ACTION=51
|
||||
LT_type="type"=7
|
||||
LT_private="private"=15
|
||||
TT_LPAREN=26
|
||||
TT_RPAREN=27
|
||||
TT_BANG=40
|
||||
TT_MLCOMMENT1=57
|
||||
TT_DNUMBER=59
|
||||
TT_TOKENS=25
|
||||
TT_ESC=65
|
||||
TT_USES=23
|
||||
TT_TOKENREF=52
|
||||
TT_NOT=38
|
||||
TT_SLCOMMENT=56
|
||||
TT_STRINGLIT=48
|
||||
TT_XDIGIT=62
|
||||
TT_WS_LOOP=64
|
||||
LT_options="options"=11
|
||||
LT_const="const"=6
|
||||
TT_ARGACTION=50
|
||||
TT_RANGE=42
|
||||
TT_PLUS=35
|
||||
TT_XNUMBER=60
|
||||
TT_COMMENT=55
|
||||
@@ -0,0 +1,889 @@
|
||||
unit dpglib.DpgParser;
|
||||
|
||||
uses
|
||||
{
|
||||
dpglib.types;
|
||||
}
|
||||
|
||||
|
||||
parser TDpgParser;
|
||||
options
|
||||
{
|
||||
defaultErrorHandler = false;
|
||||
importVocab = dpglib.DpgLexer;
|
||||
exportVocab = dpglib.DpgParser;
|
||||
k = 2;
|
||||
}
|
||||
|
||||
memberdecl
|
||||
{
|
||||
protected
|
||||
fGrammarMaker : IGrammarBehavior;
|
||||
fTool : ITool;
|
||||
fNesting : integer;
|
||||
|
||||
fExchangeDir : AnsiString;
|
||||
fGrammarFile : AnsiString;
|
||||
fGrammarUnit : AnsiString;
|
||||
|
||||
private
|
||||
function lastInRule : boolean;
|
||||
procedure checkEndRule( pToken: IToken);
|
||||
|
||||
public
|
||||
constructor Create( pParserState : IParserState;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString); overload;
|
||||
|
||||
constructor Create( pTokenBuffer : ITokenBuffer;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString); overload;
|
||||
|
||||
constructor Create( pTokenStream : ITokenStream;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString); overload;
|
||||
|
||||
destructor Destroy; override;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// grammar
|
||||
// ----------------------------------------------------------------------------
|
||||
grammar
|
||||
local
|
||||
{
|
||||
unitName: IToken;
|
||||
}
|
||||
:
|
||||
"unit" unitName=qualifiedId {fGrammarUnit := unitName.TokenText;} SEMI
|
||||
(usesDecl)?
|
||||
(constDecl)?
|
||||
(typeDecl)?
|
||||
classDecl
|
||||
{fGrammarMaker.endGrammar;}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// usesDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
usesDecl
|
||||
:
|
||||
USES
|
||||
(
|
||||
// tr:TOKENREF SEMI {fGrammarMaker.defineUses( tr);}
|
||||
// | rr:RULEREF SEMI {fGrammarMaker.defineUses( rr);}
|
||||
qualifiedUsesName SEMI
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
qualifiedUsesName
|
||||
local
|
||||
{
|
||||
id: AnsiString;
|
||||
}
|
||||
: ( r:TOKENREF | r:RULEREF ) { id := r.TokenText; }
|
||||
( WILDCARD
|
||||
( r:TOKENREF | r:RULEREF) { id := id +'.'+ r.TokenText; }
|
||||
)*
|
||||
{
|
||||
fGrammarMaker.defineUses(id);
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
constDecl
|
||||
:
|
||||
"const"
|
||||
a:ACTION {fGrammarMaker.RefConstAction( a);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// typeDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
typeDecl
|
||||
:
|
||||
"type"
|
||||
a:ACTION {fGrammarMaker.RefTypeAction( a);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
classDecl
|
||||
local
|
||||
{
|
||||
grType : integer;
|
||||
grObject : IToken;
|
||||
grSuper : IToken;
|
||||
}
|
||||
{
|
||||
grObject := nil;
|
||||
grSuper := nil;
|
||||
}
|
||||
:
|
||||
// ------------------------------------------------------------
|
||||
// Determine parser type
|
||||
// ------------------------------------------------------------
|
||||
( "lexer" { grType := 0; }
|
||||
| "parser" { grType := 1; }
|
||||
| "treeparser" { grType := 2; }
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// get class name
|
||||
// ------------------------------------------------------------
|
||||
grObject = id
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// get superclass name
|
||||
// ------------------------------------------------------------
|
||||
// (
|
||||
// LPAREN
|
||||
// grSuper=id
|
||||
// RPAREN
|
||||
// )?
|
||||
|
||||
SEMI
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Start the grammar
|
||||
// ------------------------------------------------------------
|
||||
{
|
||||
// ---------------------------------------------------------
|
||||
// Now we have enough information to start the grammar.
|
||||
// ---------------------------------------------------------
|
||||
case grType of
|
||||
0: fGrammarMaker.StartLexer( InputState.FileName,
|
||||
grObject,
|
||||
grSuper);
|
||||
|
||||
1: fGrammarMaker.StartParser( InputState.FileName,
|
||||
grObject,
|
||||
grSuper);
|
||||
|
||||
2: fGrammarMaker.StartTreeWalker( InputState.FileName,
|
||||
grObject,
|
||||
grSuper);
|
||||
end;
|
||||
|
||||
fGrammarMaker.defineGrammarUnit( fGrammarUnit);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Process optional class "options {...}" clause
|
||||
// ------------------------------------------------------------
|
||||
(classOptions)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Process optional class "tokens {...}" clause
|
||||
// But only for lexers.
|
||||
// ------------------------------------------------------------
|
||||
( {grType=0}? classTokens)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Process optional class "memberDecl {...}" clause
|
||||
// ------------------------------------------------------------
|
||||
(classMemberDecl)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Well, the rules
|
||||
// ------------------------------------------------------------
|
||||
rules
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Process optional class "memberDecl {...}" clause
|
||||
// ------------------------------------------------------------
|
||||
(classMemberDef)?
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classOptions
|
||||
// ----------------------------------------------------------------------------
|
||||
classOptions
|
||||
local
|
||||
{
|
||||
optName : IToken;
|
||||
optValue : IToken;
|
||||
}
|
||||
:
|
||||
OPTIONS
|
||||
(
|
||||
optName = id
|
||||
ASSIGN
|
||||
optValue = optionValue
|
||||
SEMI
|
||||
{fGrammarMaker.setGrammarOption( optName, optValue);}
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classTokens
|
||||
// ----------------------------------------------------------------------------
|
||||
classTokens
|
||||
:
|
||||
TOKENS
|
||||
(
|
||||
{
|
||||
tokenName := nil;
|
||||
tokenString := nil;
|
||||
}
|
||||
|
||||
(
|
||||
tokenName:TOKENREF (ASSIGN tokenString:STRINGLIT)?
|
||||
{
|
||||
fGrammarMaker.defineToken( tokenName, tokenString);
|
||||
}
|
||||
(tokenSpecOptions[tokenName])?
|
||||
|
||||
| tokenString:STRINGLIT
|
||||
{
|
||||
fGrammarMaker.defineToken( tokenName, tokenString);
|
||||
}
|
||||
(tokenSpecOptions[tokenString])?
|
||||
)
|
||||
|
||||
SEMI
|
||||
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tokenSpecOptions
|
||||
// ----------------------------------------------------------------------------
|
||||
tokenSpecOptions[ t: IToken]
|
||||
local
|
||||
{
|
||||
name : IToken;
|
||||
value : IToken;
|
||||
}
|
||||
{
|
||||
name := nil;
|
||||
value := nil;
|
||||
}
|
||||
: OPEN
|
||||
name=id ASSIGN value=optionValue
|
||||
{
|
||||
fGrammarMaker.refTokenSpecElemOption( t, name, value);
|
||||
}
|
||||
(
|
||||
name=id ASSIGN value=optionValue
|
||||
{
|
||||
fGrammarMaker.refTokenSpecElemOption( t, name, value);
|
||||
}
|
||||
)*
|
||||
CLOSE
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classMemberDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
classMemberDecl
|
||||
:
|
||||
"memberDecl"
|
||||
memberDecl:ACTION
|
||||
{fGrammarMaker.refMemberDecl(memberDecl);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classMemberDef
|
||||
// ----------------------------------------------------------------------------
|
||||
classMemberDef
|
||||
:
|
||||
"memberDef"
|
||||
memberDef:ACTION
|
||||
{fGrammarMaker.refMemberDef(memberDef);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// rules
|
||||
// ----------------------------------------------------------------------------
|
||||
rules
|
||||
:
|
||||
(rule)*
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ruleExceptionBlock
|
||||
// ----------------------------------------------------------------------------
|
||||
ruleExceptionBlock
|
||||
:
|
||||
t:"except" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
|
||||
| t:"finally" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ruleExceptionBlock
|
||||
// ----------------------------------------------------------------------------
|
||||
altExceptionBlock
|
||||
:
|
||||
t:"except" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
|
||||
| t:"finally" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// rule
|
||||
// ----------------------------------------------------------------------------
|
||||
rule
|
||||
local
|
||||
{
|
||||
access : AnsiString;
|
||||
ag : integer;
|
||||
returns : IToken;
|
||||
name : IToken;
|
||||
}
|
||||
{
|
||||
access := 'public';
|
||||
args := nil;
|
||||
name := nil;
|
||||
ag := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
// ------------------------------------------------------------
|
||||
// Parse rule scope
|
||||
// ------------------------------------------------------------
|
||||
( "public" { access := 'public'; }
|
||||
| "protected" { access := 'protected'; }
|
||||
| "private" { access := 'private'; }
|
||||
)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Parse rule name
|
||||
// ------------------------------------------------------------
|
||||
name=id
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Parse optional BANG operator
|
||||
// ------------------------------------------------------------
|
||||
// ( BANG { ag := AUTOGEN_BANG;} )?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional arguments
|
||||
// ------------------------------------------------------------
|
||||
( args:ARGACTION)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional return type
|
||||
// ------------------------------------------------------------
|
||||
( "returns" ret:ARGACTION)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Now start the rule definition
|
||||
// ------------------------------------------------------------
|
||||
{
|
||||
fGrammarMaker.defineRuleName( name, access, true, '');
|
||||
|
||||
if args <> nil then
|
||||
fGrammarMaker.refArgAction( args);
|
||||
|
||||
if ret <> nil then
|
||||
fGrammarMaker.refReturnAction( ret);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional rule options
|
||||
// ------------------------------------------------------------
|
||||
(ruleOptions)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional rule local variable declarations
|
||||
// ------------------------------------------------------------
|
||||
(
|
||||
"local"
|
||||
locals:ACTION
|
||||
{fGrammarMaker.refRuleLocals( locals);}
|
||||
)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional rule init action
|
||||
// ------------------------------------------------------------
|
||||
(
|
||||
initAction:ACTION
|
||||
{fGrammarMaker.refInitAction( initAction);}
|
||||
)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Rule block
|
||||
// ------------------------------------------------------------
|
||||
COLON
|
||||
block
|
||||
SEMI
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional exception handler
|
||||
// ------------------------------------------------------------
|
||||
( ruleExceptionBlock)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Finish the rule
|
||||
// ------------------------------------------------------------
|
||||
{ fGrammarMaker.endRule('');}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// block
|
||||
// ----------------------------------------------------------------------------
|
||||
block
|
||||
{
|
||||
INC( fNesting);
|
||||
}
|
||||
: alternative (OR alternative)* {DEC(fNesting);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// alternative
|
||||
// ----------------------------------------------------------------------------
|
||||
alternative
|
||||
local
|
||||
{
|
||||
autoGen : boolean;
|
||||
}
|
||||
{
|
||||
autoGen := true;
|
||||
}
|
||||
:
|
||||
// (BANG {autoGen := false;})?
|
||||
{fGrammarMaker.beginAlt( autoGen);}
|
||||
(elem)*
|
||||
(altExceptionBlock)?
|
||||
{fGrammarMaker.endAlt;}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// elem
|
||||
// ----------------------------------------------------------------------------
|
||||
elem
|
||||
: element (elementOptions)?
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// element options
|
||||
// ----------------------------------------------------------------------------
|
||||
elementOptions
|
||||
local
|
||||
{
|
||||
name : IToken;
|
||||
value : IToken;
|
||||
}
|
||||
: OPEN
|
||||
name=id ASSIGN value=optionValue
|
||||
{
|
||||
fGrammarMaker.refElemOption(name,value);
|
||||
}
|
||||
(
|
||||
name=id ASSIGN value=optionValue
|
||||
{
|
||||
fGrammarMaker.refElemOption(name,value);
|
||||
}
|
||||
)*
|
||||
CLOSE
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// element
|
||||
// ----------------------------------------------------------------------------
|
||||
element
|
||||
local
|
||||
{
|
||||
assignId : IToken;
|
||||
assignLabel : IToken;
|
||||
autoGen : integer;
|
||||
}
|
||||
{
|
||||
assignId := nil;
|
||||
assignLabel := nil;
|
||||
autoGen := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
(
|
||||
assignId=id ASSIGN
|
||||
(assignLabel=id COLON {checkEndRule(assignLabel);})?
|
||||
(
|
||||
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
|
||||
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
|
||||
|
|
||||
tokenRef:TOKENREF (args:ARGACTION)?
|
||||
{fGrammarMaker.refToken( assignId, tokenRef, assignLabel, args, false, autoGen, lastInRule);}
|
||||
)
|
||||
)
|
||||
|
|
||||
(assignLabel=id COLON {checkEndRule(assignLabel);})?
|
||||
(
|
||||
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
|
||||
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
|
||||
| range[assignLabel]
|
||||
| terminal[assignLabel]
|
||||
| NOT (notTerminal[assignLabel] | ebnf[ assignLabel, true])
|
||||
| ebnf[ assignLabel, false]
|
||||
)
|
||||
|
|
||||
action:ACTION
|
||||
{fGrammarMaker.refAction( action);}
|
||||
|
|
||||
semPred:SEMPRED
|
||||
{fGrammarMaker.refSemPred( semPred);}
|
||||
|
|
||||
tree
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tree
|
||||
// ----------------------------------------------------------------------------
|
||||
tree
|
||||
: lp:TREE_BEGIN { fGrammarMaker.BeginTree(lp); }
|
||||
rootNode { fGrammarMaker.BeginChildList; }
|
||||
(element)+ { fGrammarMaker.EndChildList; }
|
||||
RPAREN { fGrammarMaker.EndTree; }
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// rootNode
|
||||
// ----------------------------------------------------------------------------
|
||||
rootNode
|
||||
local
|
||||
{
|
||||
l : IToken;
|
||||
}
|
||||
: (
|
||||
l=id COLON
|
||||
{
|
||||
CheckEndRule(l);
|
||||
}
|
||||
)?
|
||||
|
||||
terminal[l]
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// range
|
||||
// ----------------------------------------------------------------------------
|
||||
range [pTokenLabel: IToken]
|
||||
local
|
||||
{
|
||||
autoGen: integer;
|
||||
}
|
||||
{
|
||||
autoGen := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
crLeft:CHARLIT
|
||||
RANGE
|
||||
crRight:CHARLIT
|
||||
(BANG {autoGen := AUTOGEN_BANG;} )?
|
||||
{fGrammarMaker.refCharRange( crLeft, crRight, pTokenLabel, autoGen, lastInRule);}
|
||||
|
|
||||
(trLeft:TOKENREF | trLeft:STRINGLIT)
|
||||
RANGE
|
||||
(trRight:TOKENREF | trRight:STRINGLIT)
|
||||
autoGen=astTypeSpec
|
||||
{fGrammarMaker.refTokenRange( trLeft, trRight, pTokenLabel, autoGen, lastInRule);}
|
||||
;
|
||||
// ----------------------------------------------------------------------------
|
||||
// terminal
|
||||
// ----------------------------------------------------------------------------
|
||||
terminal [pTokenLabel: IToken]
|
||||
local
|
||||
{
|
||||
autoGen : integer;
|
||||
}
|
||||
{
|
||||
autoGen := AUTOGEN_NONE;
|
||||
aa := nil;
|
||||
}
|
||||
:
|
||||
cl:CHARLIT
|
||||
(BANG {autoGen := AUTOGEN_BANG;} )?
|
||||
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, false, autoGen, lastInRule);}
|
||||
|
|
||||
tr:TOKENREF
|
||||
autoGen=astTypeSpec
|
||||
(aa:ARGACTION)?
|
||||
{fGrammarMaker.refToken( nil, tr, pTokenLabel, aa, false, autoGen, lastInRule);}
|
||||
|
|
||||
sl:STRINGLIT
|
||||
autoGen=astTypeSpec
|
||||
{fGrammarMaker.refStringLiteral( sl, pTokenLabel, autoGen, lastInRule);}
|
||||
|
|
||||
wc:WILDCARD
|
||||
autogen=astTypeSpec
|
||||
{fGrammarMaker.refWildCard( wc, pTokenLabel, autoGen);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// notTerminal
|
||||
// ----------------------------------------------------------------------------
|
||||
notTerminal [pTokenLabel: IToken]
|
||||
local
|
||||
{
|
||||
autoGen : integer;
|
||||
}
|
||||
{
|
||||
autoGen := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
cl:CHARLIT
|
||||
(BANG {autoGen := AUTOGEN_BANG;} )?
|
||||
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, true, autoGen, lastInRule);}
|
||||
|
|
||||
tr:TOKENREF
|
||||
autoGen=astTypeSpec
|
||||
{fGrammarMaker.refToken( nil, tr, pTokenLabel, nil, true, autoGen, lastInRule);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ebnf
|
||||
// ----------------------------------------------------------------------------
|
||||
ebnf [pTokenLabel: IToken; pTokenNot: boolean]
|
||||
:
|
||||
lp:LPAREN
|
||||
{fGrammarMaker.beginSubrule( pTokenLabel, lp, pTokenNot);}
|
||||
|
||||
(
|
||||
// ---------------------------------------------------------
|
||||
// 2nd alt and optional branch ambig due to linear approx
|
||||
// LL(2) issue. COLON ACTION matched correctly in 2nd alt.
|
||||
// ---------------------------------------------------------
|
||||
options
|
||||
{
|
||||
warnWhenFollowAmbig = false;
|
||||
}
|
||||
:
|
||||
subRuleOptions
|
||||
(aa:ACTION {fGrammarMaker.refInitAction(aa);} )?
|
||||
COLON
|
||||
|
|
||||
aa:ACTION {fGrammarMaker.refInitAction(aa);}
|
||||
COLON
|
||||
)?
|
||||
|
||||
|
||||
block
|
||||
RPAREN
|
||||
|
||||
(
|
||||
( QUEST { fGrammarMaker.optionalSubrule; }
|
||||
| STAR { fGrammarMaker.zeroOrMoreSubrule; }
|
||||
| PLUS { fGrammarMaker.oneOrMoreSubrule; }
|
||||
| AT { fGrammarMaker.nmSubrule; }
|
||||
LPAREN
|
||||
(
|
||||
m:INTEGER { fGrammarMaker.refRangeLow( StrToInt(m.TokenText)); }
|
||||
(
|
||||
COMMA { fGrammarMaker.refRangeHigh( maxint); }
|
||||
(
|
||||
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
|
||||
)?
|
||||
)?
|
||||
|
|
||||
COMMA
|
||||
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
|
||||
)
|
||||
RPAREN
|
||||
| IMPLIES {fGrammarMaker.synPred; }
|
||||
)?
|
||||
|
||||
// ( BANG {fGrammarMaker.noASTSubrule;} )?
|
||||
)
|
||||
|
||||
{fGrammarMaker.endSubRule;}
|
||||
;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// optionValue
|
||||
// ----------------------------------------------------------------------------
|
||||
optionValue returns [IToken]
|
||||
:
|
||||
result=qualifiedId
|
||||
| result:STRINGLIT
|
||||
| result:CHARLIT
|
||||
| result:INTEGER
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// subruleOptions
|
||||
// ----------------------------------------------------------------------------
|
||||
subruleOptions
|
||||
local
|
||||
{
|
||||
optName : IToken;
|
||||
optValue : IToken;
|
||||
}
|
||||
:
|
||||
OPTIONS
|
||||
(
|
||||
optName = id
|
||||
ASSIGN
|
||||
optValue = optionValue
|
||||
SEMI
|
||||
{fGrammarMaker.setSubruleOption( optName, optValue);}
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ruleOptions
|
||||
// ----------------------------------------------------------------------------
|
||||
ruleOptions
|
||||
local
|
||||
{
|
||||
optName : IToken;
|
||||
optValue : IToken;
|
||||
}
|
||||
:
|
||||
OPTIONS
|
||||
(
|
||||
optName = id
|
||||
ASSIGN
|
||||
optValue = optionValue
|
||||
SEMI
|
||||
{fGrammarMaker.setRuleOption( optName, optValue);}
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// astTypeSpec
|
||||
// ----------------------------------------------------------------------------
|
||||
astTypeSpec returns [integer]
|
||||
{
|
||||
result := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
( CARET { result := AUTOGEN_CARET; }
|
||||
| BANG { result := AUTOGEN_BANG; }
|
||||
)?
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// qualifiedId
|
||||
// ----------------------------------------------------------------------------
|
||||
qualifiedId returns [IToken]
|
||||
local
|
||||
{
|
||||
buf : AnsiString;
|
||||
a : IToken;
|
||||
}
|
||||
:
|
||||
a=id { buf := a.TokenText; }
|
||||
(
|
||||
WILDCARD a=id { buf := buf + '.' + a.TokenText; }
|
||||
)*
|
||||
{
|
||||
// -----------------------------------------------------------
|
||||
// Can either TOKENREF or RULEREF. Should really create QID or
|
||||
// something else instead.
|
||||
// -----------------------------------------------------------
|
||||
result := TToken.Create( TT_TOKENREF, buf);
|
||||
result.TokenLine := a.TokenLine;
|
||||
result.TokenColumn := a.TokenColumn;
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// id
|
||||
// ----------------------------------------------------------------------------
|
||||
id returns [IToken]
|
||||
:
|
||||
result:TOKENREF
|
||||
| result:RULEREF
|
||||
;
|
||||
|
||||
memberdef
|
||||
{
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TDpgParser.Create( pParserState : IParserState;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString);
|
||||
begin
|
||||
inherited Create( pParserState, 2);
|
||||
|
||||
fGrammarMaker := pGrammarMaker;
|
||||
fExchangeDir := pExchangeDir;
|
||||
fTool := pTool;
|
||||
fNesting := 0;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TDpgParser.Create( pTokenBuffer : ITokenBuffer;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString);
|
||||
begin
|
||||
inherited Create( pTokenBuffer, 2);
|
||||
|
||||
fGrammarMaker := pGrammarMaker;
|
||||
fExchangeDir := pExchangeDir;
|
||||
fTool := pTool;
|
||||
fNesting := 0;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TDpgParser.Create( pTokenStream : ITokenStream;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString);
|
||||
begin
|
||||
inherited Create( pTokenStream, 2);
|
||||
|
||||
fGrammarMaker := pGrammarMaker;
|
||||
fExchangeDir := pExchangeDir;
|
||||
fTool := pTool;
|
||||
fNesting := 0;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TDpgParser.Destroy;
|
||||
begin
|
||||
fGrammarMaker := nil;
|
||||
fTool := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// lastInRule
|
||||
// ============================================================================
|
||||
function TDpgParser.lastInRule: boolean;
|
||||
begin
|
||||
if (fNesting = 0) and (LA(1) in [TT_SEMI, TT_OR])
|
||||
then result := true
|
||||
else result := false;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// checkEndRule
|
||||
// ============================================================================
|
||||
procedure TDpgParser.checkEndRule( pToken: IToken);
|
||||
begin
|
||||
if pToken <> nil then
|
||||
if pToken.TokenColumn = 1 then
|
||||
fTool.Warning('Did you forget to close the previous rule?',
|
||||
InputState.FileName,
|
||||
pToken.TokenLine,
|
||||
pToken.TokenColumn);
|
||||
end;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,77 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.1.0.0r
|
||||
// Grammar: dpglib.dpgParser.g
|
||||
// ============================================================================
|
||||
unit dpglib.DpgParserTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_TREE_BEGIN = 46;
|
||||
LT_finally = 21;
|
||||
TT_QUEST = 34;
|
||||
TT_INT_RULEREF = 54;
|
||||
TT_IMPLIES = 33;
|
||||
LT_returns = 18;
|
||||
TT_WILDCARD = 41;
|
||||
TT_OR = 39;
|
||||
TT_CLOSE = 44;
|
||||
TT_WS = 63;
|
||||
LT_public = 17;
|
||||
TT_RCURLY = 28;
|
||||
TT_COMMA = 31;
|
||||
LT_parser = 9;
|
||||
TT_CHARLIT = 47;
|
||||
LT_unit = 4;
|
||||
LT_tokens = 12;
|
||||
LT_uses = 5;
|
||||
TT_SEMI = 30;
|
||||
TT_ASSIGN = 32;
|
||||
TT_OPEN = 43;
|
||||
LT_treeparser = 10;
|
||||
LT_memberdecl = 13;
|
||||
TT_OPTIONS = 24;
|
||||
TT_AT = 37;
|
||||
LT_local = 19;
|
||||
TT_SEMPRED = 22;
|
||||
TT_CARET = 45;
|
||||
TT_MLCOMMENT2 = 58;
|
||||
TT_DDIGIT = 61;
|
||||
LT_lexer = 8;
|
||||
LT_memberdef = 14;
|
||||
TT_RULEREF = 53;
|
||||
LT_except = 20;
|
||||
TT_COLON = 29;
|
||||
TT_EOF = 1;
|
||||
LT_protected = 16;
|
||||
TT_INTEGER = 49;
|
||||
TT_STAR = 36;
|
||||
TT_ACTION = 51;
|
||||
LT_type = 7;
|
||||
LT_private = 15;
|
||||
TT_LPAREN = 26;
|
||||
TT_RPAREN = 27;
|
||||
TT_BANG = 40;
|
||||
TT_MLCOMMENT1 = 57;
|
||||
TT_DNUMBER = 59;
|
||||
TT_TOKENS = 25;
|
||||
TT_ESC = 65;
|
||||
TT_USES = 23;
|
||||
TT_TOKENREF = 52;
|
||||
TT_NOT = 38;
|
||||
TT_SLCOMMENT = 56;
|
||||
TT_STRINGLIT = 48;
|
||||
TT_XDIGIT = 62;
|
||||
TT_WS_LOOP = 64;
|
||||
LT_options = 11;
|
||||
LT_const = 6;
|
||||
TT_ARGACTION = 50;
|
||||
TT_RANGE = 42;
|
||||
TT_PLUS = 35;
|
||||
TT_XNUMBER = 60;
|
||||
TT_COMMENT = 55;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,65 @@
|
||||
// $Delphi Parser Generator: dpglib.dpgParser.g -> dpglib.dpgParser.gTokens.txt$
|
||||
TDpgParser
|
||||
TT_TREE_BEGIN=46
|
||||
LT_finally="finally"=21
|
||||
TT_QUEST=34
|
||||
TT_INT_RULEREF=54
|
||||
TT_IMPLIES=33
|
||||
LT_returns="returns"=18
|
||||
TT_WILDCARD=41
|
||||
TT_OR=39
|
||||
TT_CLOSE=44
|
||||
TT_WS=63
|
||||
LT_public="public"=17
|
||||
TT_RCURLY=28
|
||||
TT_COMMA=31
|
||||
LT_parser="parser"=9
|
||||
TT_CHARLIT=47
|
||||
LT_unit="unit"=4
|
||||
LT_tokens="tokens"=12
|
||||
LT_uses="uses"=5
|
||||
TT_SEMI=30
|
||||
TT_ASSIGN=32
|
||||
TT_OPEN=43
|
||||
LT_treeparser="treeparser"=10
|
||||
LT_memberdecl="memberdecl"=13
|
||||
TT_OPTIONS=24
|
||||
TT_AT=37
|
||||
LT_local="local"=19
|
||||
TT_SEMPRED=22
|
||||
TT_CARET=45
|
||||
TT_MLCOMMENT2=58
|
||||
TT_DDIGIT=61
|
||||
LT_lexer="lexer"=8
|
||||
LT_memberdef="memberdef"=14
|
||||
TT_RULEREF=53
|
||||
LT_except="except"=20
|
||||
TT_COLON=29
|
||||
TT_EOF=1
|
||||
LT_protected="protected"=16
|
||||
TT_INTEGER=49
|
||||
TT_STAR=36
|
||||
TT_ACTION=51
|
||||
LT_type="type"=7
|
||||
LT_private="private"=15
|
||||
TT_LPAREN=26
|
||||
TT_RPAREN=27
|
||||
TT_BANG=40
|
||||
TT_MLCOMMENT1=57
|
||||
TT_DNUMBER=59
|
||||
TT_TOKENS=25
|
||||
TT_ESC=65
|
||||
TT_USES=23
|
||||
TT_TOKENREF=52
|
||||
TT_NOT=38
|
||||
TT_SLCOMMENT=56
|
||||
TT_STRINGLIT=48
|
||||
TT_XDIGIT=62
|
||||
TT_WS_LOOP=64
|
||||
LT_options="options"=11
|
||||
LT_const="const"=6
|
||||
TT_ARGACTION=50
|
||||
TT_RANGE=42
|
||||
TT_PLUS=35
|
||||
TT_XNUMBER=60
|
||||
TT_COMMENT=55
|
||||
@@ -0,0 +1,110 @@
|
||||
unit dpglib.TokenLexer;
|
||||
|
||||
lexer TTokenLexer;
|
||||
options
|
||||
{
|
||||
k = 2;
|
||||
testLiterals = false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Simple tokens
|
||||
// ----------------------------------------------------------------------------
|
||||
LPAREN : '(';
|
||||
RPAREN : ')';
|
||||
ASSIGN : '=';
|
||||
STRING : '"' (~'"')* '"';
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// DIGIT
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
DIGIT
|
||||
: '0'..'9'
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// XDIGIT
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
XDIGIT
|
||||
: '0'..'9'
|
||||
| 'a'..'f'
|
||||
| 'A'..'F'
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ID
|
||||
// ----------------------------------------------------------------------------
|
||||
ID
|
||||
: ('a'..'z' | 'A'..'Z')
|
||||
('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// INT
|
||||
// ----------------------------------------------------------------------------
|
||||
INT
|
||||
: (DIGIT)+
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WS
|
||||
// ----------------------------------------------------------------------------
|
||||
WS
|
||||
:
|
||||
(
|
||||
' '
|
||||
| '\t'
|
||||
| '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
)
|
||||
{
|
||||
_ttype := TT_SKIP;
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SLCOMMENT
|
||||
// ----------------------------------------------------------------------------
|
||||
SLCOMMENT
|
||||
: "//"
|
||||
( ~( '\r' | '\n'))*
|
||||
(
|
||||
options
|
||||
{
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
)
|
||||
{
|
||||
_ttype := TT_SKIP;
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MLCOMMENT
|
||||
// ----------------------------------------------------------------------------
|
||||
MLCOMMENT
|
||||
: "(*"
|
||||
|
||||
(
|
||||
options
|
||||
{
|
||||
greedy = false;
|
||||
generateAmbigWarnings= false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
| ~('\r' | '\n')
|
||||
)*
|
||||
|
||||
"*)"
|
||||
{
|
||||
_ttype := TT_SKIP;
|
||||
}
|
||||
;
|
||||
@@ -0,0 +1,622 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.1.0.0r
|
||||
// Grammar: dpglib.tokenLexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenLexer;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.Classes,
|
||||
dpglib.TokenLexerTokens,
|
||||
dpgrtl.lexer,
|
||||
dpgrtl.types,
|
||||
System.SysUtils;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TTokenLexer declaration
|
||||
// =========================================================================
|
||||
TTokenLexer = class( TLexer)
|
||||
|
||||
public // Protected grammar rules
|
||||
// Must callable from parser too
|
||||
procedure mDIGIT ( pCreate: boolean);
|
||||
procedure mXDIGIT ( pCreate: boolean);
|
||||
|
||||
public // Public grammar rules
|
||||
procedure mLPAREN ( pCreate: boolean);
|
||||
procedure mRPAREN ( pCreate: boolean);
|
||||
procedure mASSIGN ( pCreate: boolean);
|
||||
procedure mSTRING ( pCreate: boolean);
|
||||
procedure mID ( pCreate: boolean);
|
||||
procedure mINT ( pCreate: boolean);
|
||||
procedure mWS ( pCreate: boolean);
|
||||
procedure mSLCOMMENT ( pCreate: boolean);
|
||||
procedure mMLCOMMENT ( pCreate: boolean);
|
||||
|
||||
public
|
||||
function NextToken: IToken; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpgrtl.exception,
|
||||
dpgrtl.token;
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// mLPAREN
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mLPAREN( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_LPAREN;
|
||||
|
||||
match('(');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mRPAREN
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mRPAREN( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_RPAREN;
|
||||
|
||||
match(')');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mASSIGN
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mASSIGN( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_ASSIGN;
|
||||
|
||||
match('=');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mSTRING
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mSTRING( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_STRING;
|
||||
|
||||
match('"');
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in [#1..'!','#'..#255])) then
|
||||
begin
|
||||
matchNot('"');
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
match('"');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mDIGIT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mDIGIT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_DIGIT;
|
||||
|
||||
match( ['0'..'9']);
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mXDIGIT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mXDIGIT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_XDIGIT;
|
||||
|
||||
if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
match( ['0'..'9']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['a'..'f'])) then
|
||||
begin
|
||||
match( ['a'..'f']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'F'])) then
|
||||
begin
|
||||
match( ['A'..'F']);
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), ['0'..'9','A'..'F','a'..'f'], InputState.FileName, InputState.Line, InputState.Column);
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mID
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mID( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_ID;
|
||||
|
||||
if (( LA(1) in ['a'..'z'])) then
|
||||
begin
|
||||
match( ['a'..'z']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'Z'])) then
|
||||
begin
|
||||
match( ['A'..'Z']);
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), ['A'..'Z','a'..'z'], InputState.FileName, InputState.Line, InputState.Column);
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in ['a'..'z'])) then
|
||||
begin
|
||||
match( ['a'..'z']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'Z'])) then
|
||||
begin
|
||||
match( ['A'..'Z']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['_'])) then
|
||||
begin
|
||||
match('_');
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
match( ['0'..'9']);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mINT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mINT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_cnt_15: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_INT;
|
||||
|
||||
_cnt_15 := 0;
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
mDIGIT(false);
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
if _cnt_15 >= 1 then
|
||||
break
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), ['0'..'9'], InputState.FileName, InputState.Line, InputState.Column);
|
||||
end;
|
||||
|
||||
INC(_cnt_15);
|
||||
end;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mWS
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mWS( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_WS;
|
||||
|
||||
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
||||
begin
|
||||
match(#13);
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [' '])) then
|
||||
begin
|
||||
match(' ');
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#9])) then
|
||||
begin
|
||||
match(#9);
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#13])) then
|
||||
begin
|
||||
match(#13);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#10])) then
|
||||
begin
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), [#9..#10,#13,' '], InputState.FileName, InputState.Line, InputState.Column);
|
||||
_ttype := TT_SKIP;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mSLCOMMENT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mSLCOMMENT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_SLCOMMENT;
|
||||
|
||||
match('//');
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
|
||||
begin
|
||||
match( [#1..#9,#11..#12,#14..#255]);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
||||
begin
|
||||
match(#13);
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#13])) then
|
||||
begin
|
||||
match(#13);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#10])) then
|
||||
begin
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), [#10,#13], InputState.FileName, InputState.Line, InputState.Column);
|
||||
_ttype := TT_SKIP;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mMLCOMMENT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mMLCOMMENT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_MLCOMMENT;
|
||||
|
||||
match('(*');
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
// non-greedy exit test
|
||||
if( LA(1) in ['*']) and (LA(2) in [')']) then
|
||||
break;
|
||||
|
||||
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
||||
begin
|
||||
match(#13);
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#13])) then
|
||||
begin
|
||||
match(#13);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#10])) then
|
||||
begin
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
|
||||
begin
|
||||
match( [#1..#9,#11..#12,#14..#255]);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
match('*)');
|
||||
_ttype := TT_SKIP;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// NextToken
|
||||
// ----------------------------------------------------------------------------
|
||||
function TTokenLexer.NextToken : IToken;
|
||||
var
|
||||
_first : TCharSet;
|
||||
|
||||
begin
|
||||
_first := [#9..#10,#13,' ','"','('..')','/'..'9','=','A'..'Z','a'..'z'];
|
||||
|
||||
while( true) do
|
||||
begin
|
||||
ResetText;
|
||||
|
||||
try
|
||||
if (( LA(1) in ['(']) and (LA(2) in ['*'])) then
|
||||
begin
|
||||
mMLCOMMENT(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['('])) then
|
||||
begin
|
||||
mLPAREN(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [')'])) then
|
||||
begin
|
||||
mRPAREN(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['='])) then
|
||||
begin
|
||||
mASSIGN(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['"'])) then
|
||||
begin
|
||||
mSTRING(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'Z','a'..'z'])) then
|
||||
begin
|
||||
mID(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
mINT(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#9..#10,#13,' '])) then
|
||||
begin
|
||||
mWS(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['/'])) then
|
||||
begin
|
||||
mSLCOMMENT(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
if LA(1) = EOF_CHAR then
|
||||
begin
|
||||
uponEof;
|
||||
result := TToken.Create(TT_EOF);
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create(LA(1), _first, InputState.FileName, InputState.Line, InputState.Column);
|
||||
end;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// If we found a SKIP token, then try again...
|
||||
// --------------------------------------------------------------
|
||||
if result = nil then
|
||||
continue;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Now we have a valid token, so exit the function
|
||||
// --------------------------------------------------------------
|
||||
break;
|
||||
|
||||
except
|
||||
Raise;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,26 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.1.0.0r
|
||||
// Grammar: dpglib.tokenLexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenLexerTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_ID = 10;
|
||||
TT_STRING = 7;
|
||||
TT_EOF = 1;
|
||||
TT_XDIGIT = 9;
|
||||
TT_SLCOMMENT = 13;
|
||||
TT_ASSIGN = 6;
|
||||
TT_WS = 12;
|
||||
TT_LPAREN = 4;
|
||||
TT_RPAREN = 5;
|
||||
TT_DIGIT = 8;
|
||||
TT_MLCOMMENT = 14;
|
||||
TT_INT = 11;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,14 @@
|
||||
// $Delphi Parser Generator: dpglib.tokenLexer.g -> dpglib.tokenLexer.gTokens.txt$
|
||||
TTokenLexer
|
||||
TT_ID=10
|
||||
TT_STRING=7
|
||||
TT_EOF=1
|
||||
TT_XDIGIT=9
|
||||
TT_SLCOMMENT=13
|
||||
TT_ASSIGN=6
|
||||
TT_WS=12
|
||||
TT_LPAREN=4
|
||||
TT_RPAREN=5
|
||||
TT_DIGIT=8
|
||||
TT_MLCOMMENT=14
|
||||
TT_INT=11
|
||||
@@ -0,0 +1,87 @@
|
||||
unit dpglib.TokenParser;
|
||||
|
||||
uses
|
||||
{
|
||||
dpglib.Types;
|
||||
dpglib.StringSymbol;
|
||||
dpglib.TokenSymbol;
|
||||
}
|
||||
|
||||
parser TTokenParser;
|
||||
options
|
||||
{
|
||||
importVocab = dpglib.TokenLexer;
|
||||
k = 3;
|
||||
}
|
||||
|
||||
tokenFile [tm:ITokenManager]
|
||||
:
|
||||
name: ID
|
||||
(tokenLine[tm])*
|
||||
;
|
||||
|
||||
tokenLine [tm:ITokenManager]
|
||||
local
|
||||
{
|
||||
t : IToken;
|
||||
s : IToken;
|
||||
v : integer;
|
||||
sl: IStringSymbol;
|
||||
ts: ITokenSymbol;
|
||||
x : AnsiString;
|
||||
}
|
||||
: {
|
||||
t := nil;
|
||||
s := nil;
|
||||
}
|
||||
|
||||
( s1: STRING { s := s1; }
|
||||
|
||||
| lab: ID { t := lab; }
|
||||
ASSIGN
|
||||
s2: STRING { s := s2; }
|
||||
|
||||
| id: ID { t := id; }
|
||||
LPAREN
|
||||
para: STRING
|
||||
RPAREN
|
||||
|
||||
| id2: ID { t := id2; }
|
||||
)
|
||||
ASSIGN
|
||||
i: INT {
|
||||
v := StrToIntDef( i.TokenText, -1);
|
||||
|
||||
if s <> nil then
|
||||
begin
|
||||
ts := TStringSymbol.Create( s.TokenText);
|
||||
ts.TokenType := v;
|
||||
tm.Define(ts);
|
||||
|
||||
if t <> nil then
|
||||
begin
|
||||
ts := tm.TokenSymbol[s.TokenText];
|
||||
ts.QueryInterface( IStringSymbol, sl);
|
||||
sl.Lbl := t.TokenText;
|
||||
|
||||
tm.MapToTokenSymbol( t.TokenText, sl);
|
||||
end;
|
||||
end
|
||||
|
||||
else if t <> nil then
|
||||
begin
|
||||
x := Copy( t.TokenText, 4, Length( t.TokenText)-3);
|
||||
ts := TTokenSymbol.Create( x);
|
||||
ts.TokenType := v;
|
||||
tm.Define( ts);
|
||||
|
||||
if para <> nil then
|
||||
begin
|
||||
ts := tm.TokenSymbol[ t.TokenText];
|
||||
ts.Paraphrase := para.TokenText;
|
||||
end;
|
||||
end;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.1.0.0r
|
||||
// Grammar: dpglib.tokenParser.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenParser;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.Classes,
|
||||
dpglib.StringSymbol,
|
||||
dpglib.TokenParserTokens,
|
||||
dpglib.TokenSymbol,
|
||||
dpglib.Types,
|
||||
dpgrtl.llkparser,
|
||||
dpgrtl.types,
|
||||
System.SysUtils;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TTokenParser declaration
|
||||
// =========================================================================
|
||||
TTokenParser = class( TLLkParser)
|
||||
|
||||
public // Public grammar rules
|
||||
procedure tokenFile ( tm:ITokenManager);
|
||||
procedure tokenLine ( tm:ITokenManager);
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpgrtl.exception,
|
||||
dpgrtl.token;
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// tokenFile
|
||||
// ============================================================================
|
||||
procedure TTokenParser.tokenFile( tm:ITokenManager);
|
||||
var
|
||||
name: IToken;
|
||||
|
||||
begin
|
||||
|
||||
name := LT(1);
|
||||
match(TT_ID);
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in [TT_STRING,TT_ID])) then
|
||||
begin
|
||||
tokenLine(tm);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// tokenLine
|
||||
// ============================================================================
|
||||
procedure TTokenParser.tokenLine( tm:ITokenManager);
|
||||
var
|
||||
i: IToken;
|
||||
id: IToken;
|
||||
id2: IToken;
|
||||
lab: IToken;
|
||||
para: IToken;
|
||||
s1: IToken;
|
||||
s2: IToken;
|
||||
t : IToken;
|
||||
s : IToken;
|
||||
v : integer;
|
||||
sl: IStringSymbol;
|
||||
ts: ITokenSymbol;
|
||||
x : AnsiString;
|
||||
|
||||
begin
|
||||
|
||||
t := nil;
|
||||
s := nil;
|
||||
if (( LA(1) in [TT_STRING])) then
|
||||
begin
|
||||
s1 := LT(1);
|
||||
match(TT_STRING);
|
||||
s := s1;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_ASSIGN]) and (LA(3) in [TT_STRING])) then
|
||||
begin
|
||||
lab := LT(1);
|
||||
match(TT_ID);
|
||||
t := lab;
|
||||
match(TT_ASSIGN);
|
||||
s2 := LT(1);
|
||||
match(TT_STRING);
|
||||
s := s2;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_LPAREN])) then
|
||||
begin
|
||||
id := LT(1);
|
||||
match(TT_ID);
|
||||
t := id;
|
||||
match(TT_LPAREN);
|
||||
para := LT(1);
|
||||
match(TT_STRING);
|
||||
match(TT_RPAREN);
|
||||
end
|
||||
|
||||
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_ASSIGN]) and (LA(3) in [TT_INT])) then
|
||||
begin
|
||||
id2 := LT(1);
|
||||
match(TT_ID);
|
||||
t := id2;
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedToken.Create( LT(1), [TT_STRING,TT_ID], InputState.FileName);
|
||||
match(TT_ASSIGN);
|
||||
i := LT(1);
|
||||
match(TT_INT);
|
||||
v := StrToIntDef( i.TokenText, -1);
|
||||
|
||||
if s <> nil then
|
||||
begin
|
||||
ts := TStringSymbol.Create( s.TokenText);
|
||||
ts.TokenType := v;
|
||||
tm.Define(ts);
|
||||
|
||||
if t <> nil then
|
||||
begin
|
||||
ts := tm.TokenSymbol[s.TokenText];
|
||||
ts.QueryInterface( IStringSymbol, sl);
|
||||
sl.Lbl := t.TokenText;
|
||||
|
||||
tm.MapToTokenSymbol( t.TokenText, sl);
|
||||
end;
|
||||
end
|
||||
|
||||
else if t <> nil then
|
||||
begin
|
||||
x := Copy( t.TokenText, 4, Length( t.TokenText)-3);
|
||||
ts := TTokenSymbol.Create( x);
|
||||
ts.TokenType := v;
|
||||
tm.Define( ts);
|
||||
|
||||
if para <> nil then
|
||||
begin
|
||||
ts := tm.TokenSymbol[ t.TokenText];
|
||||
ts.Paraphrase := para.TokenText;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,26 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.1.0.0r
|
||||
// Grammar: dpglib.tokenParser.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenParserTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_ID = 10;
|
||||
TT_STRING = 7;
|
||||
TT_EOF = 1;
|
||||
TT_SLCOMMENT = 13;
|
||||
TT_XDIGIT = 9;
|
||||
TT_ASSIGN = 6;
|
||||
TT_WS = 12;
|
||||
TT_LPAREN = 4;
|
||||
TT_RPAREN = 5;
|
||||
TT_DIGIT = 8;
|
||||
TT_MLCOMMENT = 14;
|
||||
TT_INT = 11;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,14 @@
|
||||
// $Delphi Parser Generator: dpglib.tokenParser.g -> dpglib.tokenParser.gTokens.txt$
|
||||
TTokenParser
|
||||
TT_ID=10
|
||||
TT_STRING=7
|
||||
TT_EOF=1
|
||||
TT_SLCOMMENT=13
|
||||
TT_XDIGIT=9
|
||||
TT_ASSIGN=6
|
||||
TT_WS=12
|
||||
TT_LPAREN=4
|
||||
TT_RPAREN=5
|
||||
TT_DIGIT=8
|
||||
TT_MLCOMMENT=14
|
||||
TT_INT=11
|
||||
@@ -0,0 +1,349 @@
|
||||
unit z.dpglib.DpgLexer;
|
||||
|
||||
lexer TDpgLexer;
|
||||
options
|
||||
{
|
||||
testLiterals = false;
|
||||
k = 2;
|
||||
}
|
||||
|
||||
tokens
|
||||
{
|
||||
"unit";
|
||||
"uses";
|
||||
"const";
|
||||
"type";
|
||||
|
||||
"lexer";
|
||||
"parser";
|
||||
|
||||
"options";
|
||||
"tokens";
|
||||
"memberdecl";
|
||||
"memberdef";
|
||||
|
||||
"private";
|
||||
"protected";
|
||||
"public";
|
||||
|
||||
"returns";
|
||||
"local";
|
||||
|
||||
"except";
|
||||
"finally";
|
||||
|
||||
SEMPRED;
|
||||
|
||||
USES;
|
||||
OPTIONS;
|
||||
TOKENS;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Simple tokens
|
||||
// ----------------------------------------------------------------------------
|
||||
LPAREN: '(';
|
||||
RPAREN: ')';
|
||||
|
||||
RCURLY: '}';
|
||||
|
||||
COLON: ':';
|
||||
SEMI: ';';
|
||||
COMMA: ',';
|
||||
|
||||
ASSIGN: '=';
|
||||
IMPLIES: "=>";
|
||||
|
||||
QUEST: '?';
|
||||
PLUS: '+';
|
||||
STAR: '*';
|
||||
AT: '@';
|
||||
|
||||
NOT: '~';
|
||||
OR: '|';
|
||||
BANG: '!';
|
||||
|
||||
WILDCARD: '.';
|
||||
RANGE: "..";
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Character literal
|
||||
// ----------------------------------------------------------------------------
|
||||
CHARLIT
|
||||
: '\''! (ESC | ~'\'') '\''! ;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// String literal
|
||||
// ----------------------------------------------------------------------------
|
||||
STRINGLIT
|
||||
: '"' (ESC | ~'"')* '"' ;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Integer
|
||||
// ----------------------------------------------------------------------------
|
||||
INTEGER
|
||||
local
|
||||
{
|
||||
i: integer;
|
||||
v: integer;
|
||||
}
|
||||
:
|
||||
(
|
||||
DNUMBER
|
||||
{
|
||||
v := 0;
|
||||
for i:=1 to Length( TokenText) do
|
||||
begin
|
||||
v := v * 10 + ord( TokenText[i]) - ord('0');
|
||||
end;
|
||||
|
||||
TokenText := IntToStr( v);
|
||||
}
|
||||
|
|
||||
XNUMBER
|
||||
{
|
||||
v := 0;
|
||||
for i:=1 to Length( TokenText) do
|
||||
begin
|
||||
case TokenText[i] of
|
||||
'0'..'9': v := v * 16 + ord(TokenText[i]) - ord('0');
|
||||
'a'..'z': v := v * 16 + ord(TokenText[i]) - ord('a');
|
||||
'A'..'Z': v := v * 16 + ord(TokenText[i]) - ord('A');
|
||||
end;
|
||||
end;
|
||||
|
||||
TokenText := IntToStr( v);
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Argument action
|
||||
// ----------------------------------------------------------------------------
|
||||
ARGACTION
|
||||
:
|
||||
'['!
|
||||
(
|
||||
options
|
||||
{
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
| ~']'
|
||||
)*
|
||||
']'!
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Action
|
||||
// ----------------------------------------------------------------------------
|
||||
ACTION
|
||||
:
|
||||
'{'
|
||||
(
|
||||
options
|
||||
{
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
| ~'}'
|
||||
)*
|
||||
'}'
|
||||
( '?'! { _ttype := TT_SEMPRED; } )?
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Token ref
|
||||
// ----------------------------------------------------------------------------
|
||||
TOKENREF
|
||||
options
|
||||
{
|
||||
testLiterals = true;
|
||||
}
|
||||
: 'A'..'Z' ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')* ;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rule ref
|
||||
// ----------------------------------------------------------------------------
|
||||
RULEREF
|
||||
local
|
||||
{
|
||||
t: integer;
|
||||
}
|
||||
:
|
||||
t = INT_RULEREF { _ttype := t; }
|
||||
(
|
||||
{t = LT_uses}? WS_LOOP ('{' { _ttype := TT_USES; } )?
|
||||
| {t = LT_options}? WS_LOOP ('{' { _ttype := TT_OPTIONS; } )?
|
||||
| {t = LT_tokens}? WS_LOOP ('{' { _ttype := TT_TOKENS; } )?
|
||||
)?
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Internal rule ref
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
INT_RULEREF returns [integer]
|
||||
{
|
||||
_ttype := TT_RULEREF;
|
||||
}
|
||||
: 'a'..'z' ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
|
||||
{
|
||||
result := TestLiteral( _ttype);
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// COMMENT
|
||||
// ----------------------------------------------------------------------------
|
||||
COMMENT
|
||||
: SLCOMMENT { _ttype := TT_SKIP; }
|
||||
| MLCOMMENT1 { _ttype := TT_SKIP; }
|
||||
| MLCOMMENT2 { _ttype := TT_SKIP; }
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SLCOMMENT
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
SLCOMMENT
|
||||
:
|
||||
"//"
|
||||
( ~( '\r' | '\n') )*
|
||||
(
|
||||
options
|
||||
{
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
)
|
||||
;
|
||||
|
||||
// ============================================================================
|
||||
// Multi line comment version 1
|
||||
// Nested comments aren't allowed!
|
||||
// ============================================================================
|
||||
protected
|
||||
MLCOMMENT1
|
||||
:
|
||||
"(*"
|
||||
(
|
||||
options
|
||||
{
|
||||
greedy = false;
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
| .
|
||||
)*
|
||||
"*)"
|
||||
;
|
||||
|
||||
// ============================================================================
|
||||
// Multi line comment version 2
|
||||
// Nested comments aren't allowed!
|
||||
// ============================================================================
|
||||
protected
|
||||
MLCOMMENT2
|
||||
:
|
||||
"/*"
|
||||
(
|
||||
options
|
||||
{
|
||||
greedy = false;
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
| .
|
||||
)*
|
||||
"*/"
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Numbers
|
||||
// ----------------------------------------------------------------------------
|
||||
protected DNUMBER: '0'..'9' (DDIGIT)*;
|
||||
protected XNUMBER: '$'! (XDIGIT)+;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Digits
|
||||
// ----------------------------------------------------------------------------
|
||||
protected DDIGIT: '0'..'9';
|
||||
protected XDIGIT: '0'..'9' | 'a'..'f' | 'A'..'F';
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WS
|
||||
// ----------------------------------------------------------------------------
|
||||
WS
|
||||
:
|
||||
(
|
||||
options
|
||||
{
|
||||
generateAmbigWarnings = false;
|
||||
}
|
||||
: ' '
|
||||
| '\t' { tab; }
|
||||
| '\r' '\n' { newLine; }
|
||||
| '\r' { newLine; }
|
||||
| '\n' { newLine; }
|
||||
)
|
||||
{
|
||||
_ttype := TT_SKIP;
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WS_LOOP
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
WS_LOOP
|
||||
:
|
||||
(
|
||||
options
|
||||
{
|
||||
greedy = true;
|
||||
}
|
||||
: WS
|
||||
| COMMENT
|
||||
)*
|
||||
;
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Esc
|
||||
// ----------------------------------------------------------------------------
|
||||
protected
|
||||
ESC
|
||||
local
|
||||
{
|
||||
number: AnsiString;
|
||||
}
|
||||
:
|
||||
'\\'!
|
||||
(
|
||||
'r' { TokenText[ Length( TokenText)] := AnsiChar(13); }
|
||||
| 'n' { TokenText[ Length( TokenText)] := AnsiChar(10); }
|
||||
| 't' { TokenText[ Length( TokenText)] := AnsiChar(9); }
|
||||
| '\\'
|
||||
| '\''
|
||||
| '"'
|
||||
| 'x' d1:XDIGIT! d2:XDIGIT!
|
||||
{
|
||||
number := '$' + d1.TokenText + d2.TokenText;
|
||||
TokenText[ Length( TokenText)] := AnsiChar( StrToInt( number));
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
@@ -0,0 +1,798 @@
|
||||
unit z.dpglib.DpgParser;
|
||||
|
||||
uses
|
||||
{
|
||||
z.dpglib.types;
|
||||
}
|
||||
|
||||
|
||||
parser TDpgParser;
|
||||
options
|
||||
{
|
||||
defaultErrorHandler = false;
|
||||
importVocab = z.dpglib.DpgLexer;
|
||||
exportVocab = z.dpglib.DpgParser;
|
||||
k = 2;
|
||||
}
|
||||
|
||||
memberdecl
|
||||
{
|
||||
protected
|
||||
fGrammarMaker : IGrammarBehavior;
|
||||
fTool : ITool;
|
||||
fNesting : integer;
|
||||
|
||||
fExchangeDir : AnsiString;
|
||||
fGrammarFile : AnsiString;
|
||||
fGrammarUnit : AnsiString;
|
||||
|
||||
private
|
||||
function lastInRule : boolean;
|
||||
procedure checkEndRule( pToken: IToken);
|
||||
|
||||
public
|
||||
constructor Create( pParserState : IParserState;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString); overload;
|
||||
|
||||
constructor Create( pTokenBuffer : ITokenBuffer;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString); overload;
|
||||
|
||||
constructor Create( pTokenStream : ITokenStream;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString); overload;
|
||||
|
||||
destructor Destroy; override;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// grammar
|
||||
// ----------------------------------------------------------------------------
|
||||
grammar
|
||||
local
|
||||
{
|
||||
unitName: IToken;
|
||||
}
|
||||
:
|
||||
"unit" "[" unitName=qualifiedId {fGrammarUnit := unitName.TokenText;} SEMI
|
||||
(usesDecl)?
|
||||
(constDecl)?
|
||||
(typeDecl)?
|
||||
classDecl
|
||||
{fGrammarMaker.endGrammar;}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// usesDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
usesDecl
|
||||
:
|
||||
USES
|
||||
(
|
||||
// tr:TOKENREF SEMI {fGrammarMaker.defineUses( tr);}
|
||||
// | rr:RULEREF SEMI {fGrammarMaker.defineUses( rr);}
|
||||
qualifiedUsesName SEMI
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
qualifiedUsesName
|
||||
local
|
||||
{
|
||||
id: AnsiString;
|
||||
}
|
||||
: ( r:TOKENREF | r:RULEREF ) { id := r.TokenText; }
|
||||
( WILDCARD
|
||||
( r:TOKENREF | r:RULEREF) { id := id +'.'+ r.TokenText; }
|
||||
)*
|
||||
{
|
||||
fGrammarMaker.defineUses(id);
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
constDecl
|
||||
:
|
||||
"const"
|
||||
a:ACTION {fGrammarMaker.RefConstAction( a);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// typeDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
typeDecl
|
||||
:
|
||||
"type"
|
||||
a:ACTION {fGrammarMaker.RefTypeAction( a);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
classDecl
|
||||
local
|
||||
{
|
||||
grType : integer;
|
||||
grObject : IToken;
|
||||
grSuper : IToken;
|
||||
}
|
||||
{
|
||||
grObject := nil;
|
||||
grSuper := nil;
|
||||
}
|
||||
:
|
||||
// ------------------------------------------------------------
|
||||
// Determine parser type
|
||||
// ------------------------------------------------------------
|
||||
( "lexer" { grType := 0; }
|
||||
| "parser" { grType := 1; }
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// get class name
|
||||
// ------------------------------------------------------------
|
||||
grObject = id
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// get superclass name
|
||||
// ------------------------------------------------------------
|
||||
// (
|
||||
// LPAREN
|
||||
// grSuper=id
|
||||
// RPAREN
|
||||
// )?
|
||||
|
||||
SEMI
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Start the grammar
|
||||
// ------------------------------------------------------------
|
||||
{
|
||||
// ---------------------------------------------------------
|
||||
// Now we have enough information to start the grammar.
|
||||
// ---------------------------------------------------------
|
||||
case grType of
|
||||
0: fGrammarMaker.StartLexer( InputState.FileName,
|
||||
grObject,
|
||||
grSuper);
|
||||
|
||||
1: fGrammarMaker.StartParser( InputState.FileName,
|
||||
grObject,
|
||||
grSuper);
|
||||
|
||||
2: fGrammarMaker.StartTreeWalker( InputState.FileName,
|
||||
grObject,
|
||||
grSuper);
|
||||
end;
|
||||
|
||||
fGrammarMaker.defineGrammarUnit( fGrammarUnit);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Process optional class "options {...}" clause
|
||||
// ------------------------------------------------------------
|
||||
(classOptions)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Process optional class "tokens {...}" clause
|
||||
// But only for lexers.
|
||||
// ------------------------------------------------------------
|
||||
( {grType=0}? classTokens)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Process optional class "memberDecl {...}" clause
|
||||
// ------------------------------------------------------------
|
||||
(classMemberDecl)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Well, the rules
|
||||
// ------------------------------------------------------------
|
||||
rules
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Process optional class "memberDecl {...}" clause
|
||||
// ------------------------------------------------------------
|
||||
(classMemberDef)?
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classOptions
|
||||
// ----------------------------------------------------------------------------
|
||||
classOptions
|
||||
local
|
||||
{
|
||||
optName : IToken;
|
||||
optValue : IToken;
|
||||
}
|
||||
:
|
||||
OPTIONS
|
||||
(
|
||||
optName = id
|
||||
ASSIGN
|
||||
optValue = optionValue
|
||||
SEMI
|
||||
{fGrammarMaker.setGrammarOption( optName, optValue);}
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classTokens
|
||||
// ----------------------------------------------------------------------------
|
||||
classTokens
|
||||
:
|
||||
TOKENS
|
||||
(
|
||||
{
|
||||
tokenName := nil;
|
||||
tokenString := nil;
|
||||
}
|
||||
|
||||
(
|
||||
tokenName: TOKENREF (ASSIGN tokenString:STRINGLIT)?
|
||||
| tokenString: STRINGLIT
|
||||
)
|
||||
|
||||
SEMI
|
||||
{fGrammarMaker.defineToken( tokenName, tokenString);}
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classMemberDecl
|
||||
// ----------------------------------------------------------------------------
|
||||
classMemberDecl
|
||||
:
|
||||
"memberDecl"
|
||||
memberDecl:ACTION
|
||||
{fGrammarMaker.refMemberDecl(memberDecl);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// classMemberDef
|
||||
// ----------------------------------------------------------------------------
|
||||
classMemberDef
|
||||
:
|
||||
"memberDef"
|
||||
memberDef:ACTION
|
||||
{fGrammarMaker.refMemberDef(memberDef);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// rules
|
||||
// ----------------------------------------------------------------------------
|
||||
rules
|
||||
:
|
||||
(rule)*
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ruleExceptionBlock
|
||||
// ----------------------------------------------------------------------------
|
||||
ruleExceptionBlock
|
||||
:
|
||||
t:"except" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
|
||||
| t:"finally" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ruleExceptionBlock
|
||||
// ----------------------------------------------------------------------------
|
||||
altExceptionBlock
|
||||
:
|
||||
t:"except" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
|
||||
| t:"finally" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// rule
|
||||
// ----------------------------------------------------------------------------
|
||||
rule
|
||||
local
|
||||
{
|
||||
access : AnsiString;
|
||||
ag : integer;
|
||||
returns : IToken;
|
||||
name : IToken;
|
||||
}
|
||||
{
|
||||
access := 'public';
|
||||
args := nil;
|
||||
name := nil;
|
||||
ag := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
// ------------------------------------------------------------
|
||||
// Parse rule scope
|
||||
// ------------------------------------------------------------
|
||||
( "public" { access := 'public'; }
|
||||
| "protected" { access := 'protected'; }
|
||||
| "private" { access := 'private'; }
|
||||
)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Parse rule name
|
||||
// ------------------------------------------------------------
|
||||
name=id
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Parse optional BANG operator
|
||||
// ------------------------------------------------------------
|
||||
// ( BANG { ag := AUTOGEN_BANG;} )?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional arguments
|
||||
// ------------------------------------------------------------
|
||||
( args:ARGACTION)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional return type
|
||||
// ------------------------------------------------------------
|
||||
( "returns" ret:ARGACTION)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Now start the rule definition
|
||||
// ------------------------------------------------------------
|
||||
{
|
||||
fGrammarMaker.defineRuleName( name, access, true, '');
|
||||
|
||||
if args <> nil then
|
||||
fGrammarMaker.refArgAction( args);
|
||||
|
||||
if ret <> nil then
|
||||
fGrammarMaker.refReturnAction( ret);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional rule options
|
||||
// ------------------------------------------------------------
|
||||
(ruleOptions)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional rule local variable declarations
|
||||
// ------------------------------------------------------------
|
||||
(
|
||||
"local"
|
||||
locals:ACTION
|
||||
{fGrammarMaker.refRuleLocals( locals);}
|
||||
)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional rule init action
|
||||
// ------------------------------------------------------------
|
||||
(
|
||||
initAction:ACTION
|
||||
{fGrammarMaker.refInitAction( initAction);}
|
||||
)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Rule block
|
||||
// ------------------------------------------------------------
|
||||
COLON
|
||||
block
|
||||
SEMI
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Optional exception handler
|
||||
// ------------------------------------------------------------
|
||||
( ruleExceptionBlock)?
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Finish the rule
|
||||
// ------------------------------------------------------------
|
||||
{ fGrammarMaker.endRule('');}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// block
|
||||
// ----------------------------------------------------------------------------
|
||||
block
|
||||
{
|
||||
INC( fNesting);
|
||||
}
|
||||
: alternative (OR alternative)* {DEC(fNesting);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// alternative
|
||||
// ----------------------------------------------------------------------------
|
||||
alternative
|
||||
local
|
||||
{
|
||||
autoGen : boolean;
|
||||
}
|
||||
{
|
||||
autoGen := true;
|
||||
}
|
||||
:
|
||||
// (BANG {autoGen := false;})?
|
||||
{fGrammarMaker.beginAlt( autoGen);}
|
||||
(elem)*
|
||||
(altExceptionBlock)?
|
||||
{fGrammarMaker.endAlt;}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// elem
|
||||
// ----------------------------------------------------------------------------
|
||||
elem
|
||||
: element
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// element
|
||||
// ----------------------------------------------------------------------------
|
||||
element
|
||||
local
|
||||
{
|
||||
assignId : IToken;
|
||||
assignLabel : IToken;
|
||||
autoGen : integer;
|
||||
}
|
||||
{
|
||||
assignId := nil;
|
||||
assignLabel := nil;
|
||||
autoGen := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
(
|
||||
assignId=id ASSIGN
|
||||
(assignLabel=id COLON {checkEndRule(assignLabel);})?
|
||||
(
|
||||
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
|
||||
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
|
||||
|
|
||||
tokenRef:TOKENREF (args:ARGACTION)?
|
||||
{fGrammarMaker.refToken( assignId, tokenRef, assignLabel, args, false, autoGen, lastInRule);}
|
||||
)
|
||||
)
|
||||
|
|
||||
(assignLabel=id COLON {checkEndRule(assignLabel);})?
|
||||
(
|
||||
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
|
||||
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
|
||||
| range[assignLabel]
|
||||
| terminal[assignLabel]
|
||||
| NOT (notTerminal[assignLabel] | ebnf[ assignLabel, true])
|
||||
| ebnf[ assignLabel, false]
|
||||
)
|
||||
|
|
||||
action:ACTION
|
||||
{fGrammarMaker.refAction( action);}
|
||||
|
|
||||
semPred:SEMPRED
|
||||
{fGrammarMaker.refSemPred( semPred);}
|
||||
;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// range
|
||||
// ----------------------------------------------------------------------------
|
||||
range [pTokenLabel: IToken]
|
||||
local
|
||||
{
|
||||
autoGen: integer;
|
||||
}
|
||||
{
|
||||
autoGen := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
crLeft:CHARLIT
|
||||
RANGE
|
||||
crRight:CHARLIT
|
||||
(BANG {autoGen := AUTOGEN_BANG;} )?
|
||||
{fGrammarMaker.refCharRange( crLeft, crRight, pTokenLabel, autoGen, lastInRule);}
|
||||
|
|
||||
(trLeft:TOKENREF | trLeft:STRINGLIT)
|
||||
RANGE
|
||||
(trRight:TOKENREF | trRight:STRINGLIT)
|
||||
autoGen=astTypeSpec
|
||||
{fGrammarMaker.refTokenRange( trLeft, trRight, pTokenLabel, autoGen, lastInRule);}
|
||||
;
|
||||
// ----------------------------------------------------------------------------
|
||||
// terminal
|
||||
// ----------------------------------------------------------------------------
|
||||
terminal [pTokenLabel: IToken]
|
||||
local
|
||||
{
|
||||
autoGen : integer;
|
||||
}
|
||||
{
|
||||
autoGen := AUTOGEN_NONE;
|
||||
aa := nil;
|
||||
}
|
||||
:
|
||||
cl:CHARLIT
|
||||
(BANG {autoGen := AUTOGEN_BANG;} )?
|
||||
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, false, autoGen, lastInRule);}
|
||||
|
|
||||
tr:TOKENREF
|
||||
autoGen=astTypeSpec
|
||||
(aa:ARGACTION)?
|
||||
{fGrammarMaker.refToken( nil, tr, pTokenLabel, aa, false, autoGen, lastInRule);}
|
||||
|
|
||||
sl:STRINGLIT
|
||||
autoGen=astTypeSpec
|
||||
{fGrammarMaker.refStringLiteral( sl, pTokenLabel, autoGen, lastInRule);}
|
||||
|
|
||||
wc:WILDCARD
|
||||
autogen=astTypeSpec
|
||||
{fGrammarMaker.refWildCard( wc, pTokenLabel, autoGen);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// notTerminal
|
||||
// ----------------------------------------------------------------------------
|
||||
notTerminal [pTokenLabel: IToken]
|
||||
local
|
||||
{
|
||||
autoGen : integer;
|
||||
}
|
||||
{
|
||||
autoGen := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
cl:CHARLIT
|
||||
(BANG {autoGen := AUTOGEN_BANG;} )?
|
||||
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, true, autoGen, lastInRule);}
|
||||
|
|
||||
tr:TOKENREF
|
||||
autoGen=astTypeSpec
|
||||
{fGrammarMaker.refToken( nil, tr, pTokenLabel, nil, true, autoGen, lastInRule);}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ebnf
|
||||
// ----------------------------------------------------------------------------
|
||||
ebnf [pTokenLabel: IToken; pTokenNot: boolean]
|
||||
:
|
||||
lp:LPAREN
|
||||
{fGrammarMaker.beginSubrule( pTokenLabel, lp, pTokenNot);}
|
||||
|
||||
(
|
||||
// ---------------------------------------------------------
|
||||
// 2nd alt and optional branch ambig due to linear approx
|
||||
// LL(2) issue. COLON ACTION matched correctly in 2nd alt.
|
||||
// ---------------------------------------------------------
|
||||
options
|
||||
{
|
||||
warnWhenFollowAmbig = false;
|
||||
}
|
||||
:
|
||||
subRuleOptions
|
||||
(aa:ACTION {fGrammarMaker.refInitAction(aa);} )?
|
||||
COLON
|
||||
|
|
||||
aa:ACTION {fGrammarMaker.refInitAction(aa);}
|
||||
COLON
|
||||
)?
|
||||
|
||||
|
||||
block
|
||||
RPAREN
|
||||
|
||||
(
|
||||
( QUEST { fGrammarMaker.optionalSubrule; }
|
||||
| STAR { fGrammarMaker.zeroOrMoreSubrule; }
|
||||
| PLUS { fGrammarMaker.oneOrMoreSubrule; }
|
||||
| AT { fGrammarMaker.nmSubrule; }
|
||||
LPAREN
|
||||
(
|
||||
m:INTEGER { fGrammarMaker.refRangeLow( StrToInt(m.TokenText)); }
|
||||
(
|
||||
COMMA { fGrammarMaker.refRangeHigh( maxint); }
|
||||
(
|
||||
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
|
||||
)?
|
||||
)?
|
||||
|
|
||||
COMMA
|
||||
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
|
||||
)
|
||||
RPAREN
|
||||
| IMPLIES {fGrammarMaker.synPred; }
|
||||
)?
|
||||
|
||||
// ( BANG {fGrammarMaker.noASTSubrule;} )?
|
||||
)
|
||||
|
||||
{fGrammarMaker.endSubRule;}
|
||||
;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// optionValue
|
||||
// ----------------------------------------------------------------------------
|
||||
optionValue returns [IToken]
|
||||
:
|
||||
result=qualifiedId
|
||||
| result:STRINGLIT
|
||||
| result:CHARLIT
|
||||
| result:INTEGER
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// subruleOptions
|
||||
// ----------------------------------------------------------------------------
|
||||
subruleOptions
|
||||
local
|
||||
{
|
||||
optName : IToken;
|
||||
optValue : IToken;
|
||||
}
|
||||
:
|
||||
OPTIONS
|
||||
(
|
||||
optName = id
|
||||
ASSIGN
|
||||
optValue = optionValue
|
||||
SEMI
|
||||
{fGrammarMaker.setSubruleOption( optName, optValue);}
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ruleOptions
|
||||
// ----------------------------------------------------------------------------
|
||||
ruleOptions
|
||||
local
|
||||
{
|
||||
optName : IToken;
|
||||
optValue : IToken;
|
||||
}
|
||||
:
|
||||
OPTIONS
|
||||
(
|
||||
optName = id
|
||||
ASSIGN
|
||||
optValue = optionValue
|
||||
SEMI
|
||||
{fGrammarMaker.setRuleOption( optName, optValue);}
|
||||
)*
|
||||
|
||||
RCURLY
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// astTypeSpec
|
||||
// ----------------------------------------------------------------------------
|
||||
astTypeSpec returns [integer]
|
||||
{
|
||||
result := AUTOGEN_NONE;
|
||||
}
|
||||
:
|
||||
(BANG {result := AUTOGEN_BANG;})?
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// qualifiedId
|
||||
// ----------------------------------------------------------------------------
|
||||
qualifiedId returns [IToken]
|
||||
local
|
||||
{
|
||||
buf : AnsiString;
|
||||
a : IToken;
|
||||
}
|
||||
:
|
||||
a=id { buf := a.TokenText; }
|
||||
(
|
||||
WILDCARD a=id { buf := buf + '.' + a.TokenText; }
|
||||
)*
|
||||
{
|
||||
// -----------------------------------------------------------
|
||||
// Can either TOKENREF or RULEREF. Should really create QID or
|
||||
// something else instead.
|
||||
// -----------------------------------------------------------
|
||||
result := TToken.Create( TT_TOKENREF, buf);
|
||||
result.TokenLine := a.TokenLine;
|
||||
result.TokenColumn := a.TokenColumn;
|
||||
}
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// id
|
||||
// ----------------------------------------------------------------------------
|
||||
id returns [IToken]
|
||||
:
|
||||
result:TOKENREF
|
||||
| result:RULEREF
|
||||
;
|
||||
|
||||
memberdef
|
||||
{
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TDpgParser.Create( pParserState : IParserState;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString);
|
||||
begin
|
||||
inherited Create( pParserState, 2);
|
||||
|
||||
fGrammarMaker := pGrammarMaker;
|
||||
fExchangeDir := pExchangeDir;
|
||||
fTool := pTool;
|
||||
fNesting := 0;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TDpgParser.Create( pTokenBuffer : ITokenBuffer;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString);
|
||||
begin
|
||||
inherited Create( pTokenBuffer, 2);
|
||||
|
||||
fGrammarMaker := pGrammarMaker;
|
||||
fExchangeDir := pExchangeDir;
|
||||
fTool := pTool;
|
||||
fNesting := 0;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Constructor
|
||||
// ============================================================================
|
||||
constructor TDpgParser.Create( pTokenStream : ITokenStream;
|
||||
pGrammarMaker : IGrammarBehavior;
|
||||
pTool : ITool;
|
||||
pExchangeDir : AnsiString);
|
||||
begin
|
||||
inherited Create( pTokenStream, 2);
|
||||
|
||||
fGrammarMaker := pGrammarMaker;
|
||||
fExchangeDir := pExchangeDir;
|
||||
fTool := pTool;
|
||||
fNesting := 0;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// Destructor
|
||||
// ============================================================================
|
||||
destructor TDpgParser.Destroy;
|
||||
begin
|
||||
fGrammarMaker := nil;
|
||||
fTool := nil;
|
||||
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// lastInRule
|
||||
// ============================================================================
|
||||
function TDpgParser.lastInRule: boolean;
|
||||
begin
|
||||
if (fNesting = 0) and (LA(1) in [TT_SEMI, TT_OR])
|
||||
then result := true
|
||||
else result := false;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// checkEndRule
|
||||
// ============================================================================
|
||||
procedure TDpgParser.checkEndRule( pToken: IToken);
|
||||
begin
|
||||
if pToken <> nil then
|
||||
if pToken.TokenColumn = 1 then
|
||||
fTool.Warning('Did you forget to close the previous rule?',
|
||||
InputState.FileName,
|
||||
pToken.TokenLine,
|
||||
pToken.TokenColumn);
|
||||
end;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: lexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.DpgLexerTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_EOF = 1;
|
||||
LT_unit = 4;
|
||||
LT_uses = 5;
|
||||
LT_const = 6;
|
||||
LT_type = 7;
|
||||
LT_lexer = 8;
|
||||
LT_parser = 9;
|
||||
LT_options = 10;
|
||||
LT_tokens = 11;
|
||||
LT_memberdecl = 12;
|
||||
LT_memberdef = 13;
|
||||
LT_private = 14;
|
||||
LT_protected = 15;
|
||||
LT_public = 16;
|
||||
LT_returns = 17;
|
||||
LT_local = 18;
|
||||
LT_except = 19;
|
||||
LT_finally = 20;
|
||||
TT_SEMPRED = 21;
|
||||
TT_USES = 22;
|
||||
TT_OPTIONS = 23;
|
||||
TT_TOKENS = 24;
|
||||
TT_LPAREN = 25;
|
||||
TT_RPAREN = 26;
|
||||
TT_RCURLY = 27;
|
||||
TT_COLON = 28;
|
||||
TT_SEMI = 29;
|
||||
TT_COMMA = 30;
|
||||
TT_ASSIGN = 31;
|
||||
TT_IMPLIES = 32;
|
||||
TT_QUEST = 33;
|
||||
TT_PLUS = 34;
|
||||
TT_STAR = 35;
|
||||
TT_AT = 36;
|
||||
TT_NOT = 37;
|
||||
TT_OR = 38;
|
||||
TT_BANG = 39;
|
||||
TT_WILDCARD = 40;
|
||||
TT_RANGE = 41;
|
||||
TT_CHARLIT = 42;
|
||||
TT_STRINGLIT = 43;
|
||||
TT_INTEGER = 44;
|
||||
TT_ARGACTION = 45;
|
||||
TT_ACTION = 46;
|
||||
TT_TOKENREF = 47;
|
||||
TT_RULEREF = 48;
|
||||
TT_INT_RULEREF = 49;
|
||||
TT_COMMENT = 50;
|
||||
TT_SLCOMMENT = 51;
|
||||
TT_MLCOMMENT1 = 52;
|
||||
TT_MLCOMMENT2 = 53;
|
||||
TT_DNUMBER = 54;
|
||||
TT_XNUMBER = 55;
|
||||
TT_DDIGIT = 56;
|
||||
TT_XDIGIT = 57;
|
||||
TT_WS = 58;
|
||||
TT_WS_LOOP = 59;
|
||||
TT_ESC = 60;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,60 @@
|
||||
// $Delphi Parser Generator: lexer.g -> lexer.gTokens.txt$
|
||||
TDpgLexer
|
||||
TT_EOF=1
|
||||
LT_unit="unit"=4
|
||||
LT_uses="uses"=5
|
||||
LT_const="const"=6
|
||||
LT_type="type"=7
|
||||
LT_lexer="lexer"=8
|
||||
LT_parser="parser"=9
|
||||
LT_options="options"=10
|
||||
LT_tokens="tokens"=11
|
||||
LT_memberdecl="memberdecl"=12
|
||||
LT_memberdef="memberdef"=13
|
||||
LT_private="private"=14
|
||||
LT_protected="protected"=15
|
||||
LT_public="public"=16
|
||||
LT_returns="returns"=17
|
||||
LT_local="local"=18
|
||||
LT_except="except"=19
|
||||
LT_finally="finally"=20
|
||||
TT_SEMPRED=21
|
||||
TT_USES=22
|
||||
TT_OPTIONS=23
|
||||
TT_TOKENS=24
|
||||
TT_LPAREN=25
|
||||
TT_RPAREN=26
|
||||
TT_RCURLY=27
|
||||
TT_COLON=28
|
||||
TT_SEMI=29
|
||||
TT_COMMA=30
|
||||
TT_ASSIGN=31
|
||||
TT_IMPLIES=32
|
||||
TT_QUEST=33
|
||||
TT_PLUS=34
|
||||
TT_STAR=35
|
||||
TT_AT=36
|
||||
TT_NOT=37
|
||||
TT_OR=38
|
||||
TT_BANG=39
|
||||
TT_WILDCARD=40
|
||||
TT_RANGE=41
|
||||
TT_CHARLIT=42
|
||||
TT_STRINGLIT=43
|
||||
TT_INTEGER=44
|
||||
TT_ARGACTION=45
|
||||
TT_ACTION=46
|
||||
TT_TOKENREF=47
|
||||
TT_RULEREF=48
|
||||
TT_INT_RULEREF=49
|
||||
TT_COMMENT=50
|
||||
TT_SLCOMMENT=51
|
||||
TT_MLCOMMENT1=52
|
||||
TT_MLCOMMENT2=53
|
||||
TT_DNUMBER=54
|
||||
TT_XNUMBER=55
|
||||
TT_DDIGIT=56
|
||||
TT_XDIGIT=57
|
||||
TT_WS=58
|
||||
TT_WS_LOOP=59
|
||||
TT_ESC=60
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.DpgLexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.DpgLexerTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_EOF = 1;
|
||||
LT_unit = 4;
|
||||
LT_uses = 5;
|
||||
LT_const = 6;
|
||||
LT_type = 7;
|
||||
LT_lexer = 8;
|
||||
LT_parser = 9;
|
||||
LT_options = 10;
|
||||
LT_tokens = 11;
|
||||
LT_memberdecl = 12;
|
||||
LT_memberdef = 13;
|
||||
LT_private = 14;
|
||||
LT_protected = 15;
|
||||
LT_public = 16;
|
||||
LT_returns = 17;
|
||||
LT_local = 18;
|
||||
LT_except = 19;
|
||||
LT_finally = 20;
|
||||
TT_SEMPRED = 21;
|
||||
TT_USES = 22;
|
||||
TT_OPTIONS = 23;
|
||||
TT_TOKENS = 24;
|
||||
TT_LPAREN = 25;
|
||||
TT_RPAREN = 26;
|
||||
TT_RCURLY = 27;
|
||||
TT_COLON = 28;
|
||||
TT_SEMI = 29;
|
||||
TT_COMMA = 30;
|
||||
TT_ASSIGN = 31;
|
||||
TT_IMPLIES = 32;
|
||||
TT_QUEST = 33;
|
||||
TT_PLUS = 34;
|
||||
TT_STAR = 35;
|
||||
TT_AT = 36;
|
||||
TT_NOT = 37;
|
||||
TT_OR = 38;
|
||||
TT_BANG = 39;
|
||||
TT_WILDCARD = 40;
|
||||
TT_RANGE = 41;
|
||||
TT_CHARLIT = 42;
|
||||
TT_STRINGLIT = 43;
|
||||
TT_INTEGER = 44;
|
||||
TT_ARGACTION = 45;
|
||||
TT_ACTION = 46;
|
||||
TT_TOKENREF = 47;
|
||||
TT_RULEREF = 48;
|
||||
TT_INT_RULEREF = 49;
|
||||
TT_COMMENT = 50;
|
||||
TT_SLCOMMENT = 51;
|
||||
TT_MLCOMMENT1 = 52;
|
||||
TT_MLCOMMENT2 = 53;
|
||||
TT_DNUMBER = 54;
|
||||
TT_XNUMBER = 55;
|
||||
TT_DDIGIT = 56;
|
||||
TT_XDIGIT = 57;
|
||||
TT_WS = 58;
|
||||
TT_WS_LOOP = 59;
|
||||
TT_ESC = 60;
|
||||
|
||||
implementation
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.DpgParser.g
|
||||
// ============================================================================
|
||||
unit dpglib.DpgParserTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_EOF = 1;
|
||||
LT_unit = 4;
|
||||
LT_uses = 5;
|
||||
LT_const = 6;
|
||||
LT_type = 7;
|
||||
LT_lexer = 8;
|
||||
LT_parser = 9;
|
||||
LT_options = 10;
|
||||
LT_tokens = 11;
|
||||
LT_memberdecl = 12;
|
||||
LT_memberdef = 13;
|
||||
LT_private = 14;
|
||||
LT_protected = 15;
|
||||
LT_public = 16;
|
||||
LT_returns = 17;
|
||||
LT_local = 18;
|
||||
LT_except = 19;
|
||||
LT_finally = 20;
|
||||
TT_SEMPRED = 21;
|
||||
TT_USES = 22;
|
||||
TT_OPTIONS = 23;
|
||||
TT_TOKENS = 24;
|
||||
TT_LPAREN = 25;
|
||||
TT_RPAREN = 26;
|
||||
TT_RCURLY = 27;
|
||||
TT_COLON = 28;
|
||||
TT_SEMI = 29;
|
||||
TT_COMMA = 30;
|
||||
TT_ASSIGN = 31;
|
||||
TT_IMPLIES = 32;
|
||||
TT_QUEST = 33;
|
||||
TT_PLUS = 34;
|
||||
TT_STAR = 35;
|
||||
TT_AT = 36;
|
||||
TT_NOT = 37;
|
||||
TT_OR = 38;
|
||||
TT_BANG = 39;
|
||||
TT_WILDCARD = 40;
|
||||
TT_RANGE = 41;
|
||||
TT_CHARLIT = 42;
|
||||
TT_STRINGLIT = 43;
|
||||
TT_INTEGER = 44;
|
||||
TT_ARGACTION = 45;
|
||||
TT_ACTION = 46;
|
||||
TT_TOKENREF = 47;
|
||||
TT_RULEREF = 48;
|
||||
TT_INT_RULEREF = 49;
|
||||
TT_COMMENT = 50;
|
||||
TT_SLCOMMENT = 51;
|
||||
TT_MLCOMMENT1 = 52;
|
||||
TT_MLCOMMENT2 = 53;
|
||||
TT_DNUMBER = 54;
|
||||
TT_XNUMBER = 55;
|
||||
TT_DDIGIT = 56;
|
||||
TT_XDIGIT = 57;
|
||||
TT_WS = 58;
|
||||
TT_WS_LOOP = 59;
|
||||
TT_ESC = 60;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,622 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.TokenLexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenLexer;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes,
|
||||
SysUtils,
|
||||
dpglib.TokenLexerTokens,
|
||||
dpgrtl.lexer,
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TTokenLexer declaration
|
||||
// =========================================================================
|
||||
TTokenLexer = class( TLexer)
|
||||
|
||||
public // Protected grammar rules
|
||||
// Must callable from parser too
|
||||
procedure mDIGIT ( pCreate: boolean);
|
||||
procedure mXDIGIT ( pCreate: boolean);
|
||||
|
||||
public // Public grammar rules
|
||||
procedure mLPAREN ( pCreate: boolean);
|
||||
procedure mRPAREN ( pCreate: boolean);
|
||||
procedure mASSIGN ( pCreate: boolean);
|
||||
procedure mSTRING ( pCreate: boolean);
|
||||
procedure mID ( pCreate: boolean);
|
||||
procedure mINT ( pCreate: boolean);
|
||||
procedure mWS ( pCreate: boolean);
|
||||
procedure mSLCOMMENT ( pCreate: boolean);
|
||||
procedure mMLCOMMENT ( pCreate: boolean);
|
||||
|
||||
public
|
||||
function NextToken: IToken; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpgrtl.exception,
|
||||
dpgrtl.token;
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// mLPAREN
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mLPAREN( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_LPAREN;
|
||||
|
||||
match('(');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mRPAREN
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mRPAREN( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_RPAREN;
|
||||
|
||||
match(')');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mASSIGN
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mASSIGN( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_ASSIGN;
|
||||
|
||||
match('=');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mSTRING
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mSTRING( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_STRING;
|
||||
|
||||
match('"');
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in [#1..'!','#'..#255])) then
|
||||
begin
|
||||
matchNot('"');
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
match('"');
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mDIGIT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mDIGIT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_DIGIT;
|
||||
|
||||
match( ['0'..'9']);
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mXDIGIT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mXDIGIT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_XDIGIT;
|
||||
|
||||
if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
match( ['0'..'9']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['a'..'f'])) then
|
||||
begin
|
||||
match( ['a'..'f']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'F'])) then
|
||||
begin
|
||||
match( ['A'..'F']);
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), ['0'..'9','A'..'F','a'..'f'], InputState.FileName, InputState.Line, InputState.Column);
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mID
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mID( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_ID;
|
||||
|
||||
if (( LA(1) in ['a'..'z'])) then
|
||||
begin
|
||||
match( ['a'..'z']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'Z'])) then
|
||||
begin
|
||||
match( ['A'..'Z']);
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), ['A'..'Z','a'..'z'], InputState.FileName, InputState.Line, InputState.Column);
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in ['a'..'z'])) then
|
||||
begin
|
||||
match( ['a'..'z']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'Z'])) then
|
||||
begin
|
||||
match( ['A'..'Z']);
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['_'])) then
|
||||
begin
|
||||
match('_');
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
match( ['0'..'9']);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mINT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mINT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_cnt_15: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_INT;
|
||||
|
||||
_cnt_15 := 0;
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
mDIGIT(false);
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
if _cnt_15 >= 1 then
|
||||
break
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), ['0'..'9'], InputState.FileName, InputState.Line, InputState.Column);
|
||||
end;
|
||||
|
||||
INC(_cnt_15);
|
||||
end;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mWS
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mWS( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_WS;
|
||||
|
||||
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
||||
begin
|
||||
match(#13);
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [' '])) then
|
||||
begin
|
||||
match(' ');
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#9])) then
|
||||
begin
|
||||
match(#9);
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#13])) then
|
||||
begin
|
||||
match(#13);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#10])) then
|
||||
begin
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), [#9..#10,#13,' '], InputState.FileName, InputState.Line, InputState.Column);
|
||||
_ttype := TT_SKIP;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mSLCOMMENT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mSLCOMMENT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_SLCOMMENT;
|
||||
|
||||
match('//');
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
|
||||
begin
|
||||
match( [#1..#9,#11..#12,#14..#255]);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
||||
begin
|
||||
match(#13);
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#13])) then
|
||||
begin
|
||||
match(#13);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#10])) then
|
||||
begin
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create( LA(1), [#10,#13], InputState.FileName, InputState.Line, InputState.Column);
|
||||
_ttype := TT_SKIP;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// mMLCOMMENT
|
||||
// ============================================================================
|
||||
procedure TTokenLexer.mMLCOMMENT( pCreate: boolean);
|
||||
var
|
||||
_begin: integer;
|
||||
_save: integer;
|
||||
_token: IToken;
|
||||
_ttype: integer;
|
||||
|
||||
begin
|
||||
_begin := Length( TokenText) +1;
|
||||
_token := nil;
|
||||
_ttype := TT_MLCOMMENT;
|
||||
|
||||
match('(*');
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
// non-greedy exit test
|
||||
if( LA(1) in ['*']) and (LA(2) in [')']) then
|
||||
break;
|
||||
|
||||
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
||||
begin
|
||||
match(#13);
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#13])) then
|
||||
begin
|
||||
match(#13);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#10])) then
|
||||
begin
|
||||
match(#10);
|
||||
newLine;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
|
||||
begin
|
||||
match( [#1..#9,#11..#12,#14..#255]);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
match('*)');
|
||||
_ttype := TT_SKIP;
|
||||
|
||||
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
||||
begin
|
||||
_token := makeToken( _ttype);
|
||||
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
||||
end;
|
||||
|
||||
ReturnToken := _token;
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// NextToken
|
||||
// ----------------------------------------------------------------------------
|
||||
function TTokenLexer.NextToken : IToken;
|
||||
var
|
||||
_first : TCharSet;
|
||||
|
||||
begin
|
||||
_first := [#9..#10,#13,' ','"','('..')','/'..'9','=','A'..'Z','a'..'z'];
|
||||
|
||||
while( true) do
|
||||
begin
|
||||
ResetText;
|
||||
|
||||
try
|
||||
if (( LA(1) in ['(']) and (LA(2) in ['*'])) then
|
||||
begin
|
||||
mMLCOMMENT(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['('])) then
|
||||
begin
|
||||
mLPAREN(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [')'])) then
|
||||
begin
|
||||
mRPAREN(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['='])) then
|
||||
begin
|
||||
mASSIGN(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['"'])) then
|
||||
begin
|
||||
mSTRING(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['A'..'Z','a'..'z'])) then
|
||||
begin
|
||||
mID(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['0'..'9'])) then
|
||||
begin
|
||||
mINT(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [#9..#10,#13,' '])) then
|
||||
begin
|
||||
mWS(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else if (( LA(1) in ['/'])) then
|
||||
begin
|
||||
mSLCOMMENT(true);
|
||||
result := ReturnToken;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
if LA(1) = EOF_CHAR then
|
||||
begin
|
||||
uponEof;
|
||||
result := TToken.Create(TT_EOF);
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedChar.Create(LA(1), _first, InputState.FileName, InputState.Line, InputState.Column);
|
||||
end;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// If we found a SKIP token, then try again...
|
||||
// --------------------------------------------------------------
|
||||
if result = nil then
|
||||
continue;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Now we have a valid token, so exit the function
|
||||
// --------------------------------------------------------------
|
||||
break;
|
||||
|
||||
except
|
||||
Raise;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,26 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.TokenLexer.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenLexerTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_EOF = 1;
|
||||
TT_LPAREN = 4;
|
||||
TT_RPAREN = 5;
|
||||
TT_ASSIGN = 6;
|
||||
TT_STRING = 7;
|
||||
TT_DIGIT = 8;
|
||||
TT_XDIGIT = 9;
|
||||
TT_ID = 10;
|
||||
TT_INT = 11;
|
||||
TT_WS = 12;
|
||||
TT_SLCOMMENT = 13;
|
||||
TT_MLCOMMENT = 14;
|
||||
|
||||
implementation
|
||||
end.
|
||||
@@ -0,0 +1,161 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.TokenParser.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenParser;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes,
|
||||
SysUtils,
|
||||
dpglib.StringSymbol,
|
||||
dpglib.TokenParserTokens,
|
||||
dpglib.TokenSymbol,
|
||||
dpglib.Types,
|
||||
dpgrtl.llkparser,
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
// =========================================================================
|
||||
// Class TTokenParser declaration
|
||||
// =========================================================================
|
||||
TTokenParser = class( TLLkParser)
|
||||
|
||||
public // Public grammar rules
|
||||
procedure tokenFile ( tm:ITokenManager);
|
||||
procedure tokenLine ( tm:ITokenManager);
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpgrtl.exception,
|
||||
dpgrtl.token;
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// tokenFile
|
||||
// ============================================================================
|
||||
procedure TTokenParser.tokenFile( tm:ITokenManager);
|
||||
var
|
||||
name: IToken;
|
||||
|
||||
begin
|
||||
|
||||
name := LT(1);
|
||||
match(TT_ID);
|
||||
|
||||
while(true) do
|
||||
begin
|
||||
if (( LA(1) in [TT_STRING,TT_ID])) then
|
||||
begin
|
||||
tokenLine(tm);
|
||||
end
|
||||
|
||||
else
|
||||
break;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
// ============================================================================
|
||||
// tokenLine
|
||||
// ============================================================================
|
||||
procedure TTokenParser.tokenLine( tm:ITokenManager);
|
||||
var
|
||||
i: IToken;
|
||||
id: IToken;
|
||||
id2: IToken;
|
||||
lab: IToken;
|
||||
para: IToken;
|
||||
s1: IToken;
|
||||
s2: IToken;
|
||||
t : IToken;
|
||||
s : IToken;
|
||||
v : integer;
|
||||
sl: IStringSymbol;
|
||||
ts: ITokenSymbol;
|
||||
x : AnsiString;
|
||||
|
||||
begin
|
||||
|
||||
t := nil;
|
||||
s := nil;
|
||||
if (( LA(1) in [TT_STRING])) then
|
||||
begin
|
||||
s1 := LT(1);
|
||||
match(TT_STRING);
|
||||
s := s1;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_ASSIGN]) and (LA(3) in [TT_STRING])) then
|
||||
begin
|
||||
lab := LT(1);
|
||||
match(TT_ID);
|
||||
t := lab;
|
||||
match(TT_ASSIGN);
|
||||
s2 := LT(1);
|
||||
match(TT_STRING);
|
||||
s := s2;
|
||||
end
|
||||
|
||||
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_LPAREN])) then
|
||||
begin
|
||||
id := LT(1);
|
||||
match(TT_ID);
|
||||
t := id;
|
||||
match(TT_LPAREN);
|
||||
para := LT(1);
|
||||
match(TT_STRING);
|
||||
match(TT_RPAREN);
|
||||
end
|
||||
|
||||
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_ASSIGN]) and (LA(3) in [TT_INT])) then
|
||||
begin
|
||||
id2 := LT(1);
|
||||
match(TT_ID);
|
||||
t := id2;
|
||||
end
|
||||
|
||||
else
|
||||
Raise EMismatchedToken.Create( LT(1), [TT_STRING,TT_ID], InputState.FileName);
|
||||
match(TT_ASSIGN);
|
||||
i := LT(1);
|
||||
match(TT_INT);
|
||||
v := StrToIntDef( i.TokenText, -1);
|
||||
|
||||
if s <> nil then
|
||||
begin
|
||||
ts := TStringSymbol.Create( s.TokenText);
|
||||
ts.TokenType := v;
|
||||
tm.Define(ts);
|
||||
|
||||
if t <> nil then
|
||||
begin
|
||||
ts := tm.TokenSymbol[s.TokenText];
|
||||
ts.QueryInterface( IStringSymbol, sl);
|
||||
sl.Lbl := t.TokenText;
|
||||
|
||||
tm.MapToTokenSymbol( t.TokenText, sl);
|
||||
end;
|
||||
end
|
||||
|
||||
else if t <> nil then
|
||||
begin
|
||||
x := Copy( t.TokenText, 4, Length( t.TokenText)-3);
|
||||
ts := TTokenSymbol.Create( x);
|
||||
ts.TokenType := v;
|
||||
tm.Define( ts);
|
||||
|
||||
if para <> nil then
|
||||
begin
|
||||
ts := tm.TokenSymbol[ t.TokenText];
|
||||
ts.Paraphrase := para.TokenText;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,26 @@
|
||||
// ============================================================================
|
||||
// This file is generated by the Delphi Parser Generator.
|
||||
// ----------------------------------------------------------------------------
|
||||
// DPG version: 2.0.1.0r
|
||||
// Grammar: dpglib.TokenParser.g
|
||||
// ============================================================================
|
||||
unit dpglib.TokenParserTokens;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
TT_EOF = 1;
|
||||
TT_LPAREN = 4;
|
||||
TT_RPAREN = 5;
|
||||
TT_ASSIGN = 6;
|
||||
TT_STRING = 7;
|
||||
TT_DIGIT = 8;
|
||||
TT_XDIGIT = 9;
|
||||
TT_ID = 10;
|
||||
TT_INT = 11;
|
||||
TT_WS = 12;
|
||||
TT_SLCOMMENT = 13;
|
||||
TT_MLCOMMENT = 14;
|
||||
|
||||
implementation
|
||||
end.
|
||||
Reference in New Issue
Block a user