Initial check in rtl
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
bin
|
||||
dcu
|
||||
prj.dpgxcon\Win32
|
||||
prj.dpgxcon\Win64
|
||||
|
||||
*.res
|
||||
*.identcache
|
||||
*.local
|
||||
*.dsk
|
||||
*.dsv
|
||||
|
||||
# documentation intermediate files (TeX)
|
||||
*.aux
|
||||
*.bmt
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package mr.dpgrtl;
|
||||
|
||||
{$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;
|
||||
|
||||
contains
|
||||
dpgrtl.charbuffer in '..\..\src.rtl\dpgrtl.charbuffer.pas',
|
||||
dpgrtl.charqueue in '..\..\src.rtl\dpgrtl.charqueue.pas',
|
||||
dpgrtl.exception in '..\..\src.rtl\dpgrtl.exception.pas',
|
||||
dpgrtl.inputbuffer in '..\..\src.rtl\dpgrtl.inputbuffer.pas',
|
||||
dpgrtl.lexer in '..\..\src.rtl\dpgrtl.lexer.pas',
|
||||
dpgrtl.lexerstate in '..\..\src.rtl\dpgrtl.lexerstate.pas',
|
||||
dpgrtl.llkparser in '..\..\src.rtl\dpgrtl.llkparser.pas',
|
||||
dpgrtl.parser in '..\..\src.rtl\dpgrtl.parser.pas',
|
||||
dpgrtl.parserstate in '..\..\src.rtl\dpgrtl.parserstate.pas',
|
||||
dpgrtl.stringmap in '..\..\src.rtl\dpgrtl.stringmap.pas',
|
||||
dpgrtl.token in '..\..\src.rtl\dpgrtl.token.pas',
|
||||
dpgrtl.tokenbuffer in '..\..\src.rtl\dpgrtl.tokenbuffer.pas',
|
||||
dpgrtl.tokenqueue in '..\..\src.rtl\dpgrtl.tokenqueue.pas',
|
||||
dpgrtl.treeparser in '..\..\src.rtl\dpgrtl.treeparser.pas',
|
||||
dpgrtl.treeparserstate in '..\..\src.rtl\dpgrtl.treeparserstate.pas',
|
||||
dpgrtl.types in '..\..\src.rtl\dpgrtl.types.pas',
|
||||
dpgrtl.astBase in '..\..\src.rtl\ast\dpgrtl.astBase.pas',
|
||||
dpgrtl.astCommon in '..\..\src.rtl\ast\dpgrtl.astCommon.pas',
|
||||
dpgrtl.astFactory in '..\..\src.rtl\ast\dpgrtl.astFactory.pas',
|
||||
dpgrtl.astPair in '..\..\src.rtl\ast\dpgrtl.astPair.pas';
|
||||
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,357 @@
|
||||
{
|
||||
* A Child-Sibling Tree.
|
||||
*
|
||||
* A tree with PLUS at the root and with two children 3 and 4 is
|
||||
* structured as:
|
||||
*
|
||||
* PLUS
|
||||
* |
|
||||
* 3 -- 4
|
||||
*
|
||||
* and can be specified easily in LISP notation as
|
||||
*
|
||||
* (PLUS 3 4)
|
||||
*
|
||||
* where every '(' starts a new subtree.
|
||||
*
|
||||
* These trees are particular useful for translators because of
|
||||
* the flexibility of the children lists. They are also very easy
|
||||
* to walk automatically, whereas trees with specific children
|
||||
* reference fields can't easily be walked automatically.
|
||||
*
|
||||
* This class contains the basic support for an AST.
|
||||
* Most people will create ASTs that are subclasses of
|
||||
* BaseAST or of CommonAST.
|
||||
*/
|
||||
}
|
||||
unit dpgrtl.astBase;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
Generics.Collections,
|
||||
dpgrtl.Token;
|
||||
|
||||
|
||||
type
|
||||
TAST = class;
|
||||
TASTList = TList<TAST>;
|
||||
|
||||
TAST = class
|
||||
protected
|
||||
fDown : TAST;
|
||||
fRight : TAST;
|
||||
|
||||
fAstText : AnsiString;
|
||||
fAstType : integer;
|
||||
fAstLine : integer;
|
||||
fAstColumn : integer;
|
||||
|
||||
private
|
||||
fVerbose : boolean; // verbose string conversion
|
||||
fTokenNames : TStringList;
|
||||
|
||||
private
|
||||
procedure DoFindAll( NodeToSearch : TAST;
|
||||
// v : Vector;
|
||||
Target : TAST;
|
||||
PartialMatch : boolean);
|
||||
|
||||
protected
|
||||
function GetNumberofChildren: integer;
|
||||
|
||||
function GetEquals( Node : TAST): boolean; virtual;
|
||||
function GetEqualsList( Node : TAST): boolean; virtual;
|
||||
function GetEqualsListPartial( Node : TAST): boolean; virtual;
|
||||
function GetEqualsTree( Node : TAST): boolean; virtual;
|
||||
function GetEqualsTreePartial( Node : TAST): boolean; virtual;
|
||||
|
||||
function GetTokenNames : TStringList;
|
||||
|
||||
procedure SetVerbose( Verbose : boolean;
|
||||
Names : TStringList);
|
||||
|
||||
public
|
||||
procedure Initialize( AstType : integer;
|
||||
AstText : AnsiString); overload; virtual; abstract;
|
||||
|
||||
procedure Initialize( Node : TAST); overload; virtual; abstract;
|
||||
procedure Initialize( Token : TToken); overload; virtual; abstract;
|
||||
|
||||
procedure AddChild( node: TAST);
|
||||
procedure RemoveChildren;
|
||||
|
||||
public
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
|
||||
public
|
||||
property NumberOfChildren : integer read GetNumberofChildren;
|
||||
|
||||
property NextSibling : TAST read fRight write fRight;
|
||||
property FirstChild : TAST read fDown write fDown;
|
||||
|
||||
property AstText : AnsiString read fAstText write fAstText;
|
||||
property AstType : integer read fAstType write fAstType;
|
||||
property AstLine : integer read fAstLine write fAstLine;
|
||||
property AstColumn : integer read fAstColumn write fAstColumn;
|
||||
|
||||
property Equals [n: TAST]: boolean read GetEquals;
|
||||
property EqualsList [n: TAST]: boolean read GetEqualsList;
|
||||
property EqualsListPartial [n: TAST]: boolean read GetEqualsListPartial;
|
||||
property EqualsTree [n: TAST]: boolean read GetEqualsTree;
|
||||
property EqualsTreePartial [n: TAST]: boolean read GetEqualsTreepartial;
|
||||
end;
|
||||
|
||||
TASTClass = class of TAST;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
{ TastBase }
|
||||
|
||||
procedure TAST.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
fTokenNames := TStringList.Create;
|
||||
end;
|
||||
|
||||
procedure TAST.BeforeDestruction;
|
||||
begin
|
||||
fTokenNames.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// DoFindAll
|
||||
// ================================================================================================
|
||||
procedure TAST.DoFindAll(NodeToSearch, Target: TAST; PartialMatch: boolean);
|
||||
var
|
||||
sibling: TAST;
|
||||
|
||||
begin
|
||||
// start walking sibling lists, looking for matches
|
||||
sibling := NodeToSearch;
|
||||
|
||||
while Assigned(sibling) do
|
||||
begin
|
||||
if ( PartialMatch and sibling.EqualsTreePartial[Target]) or
|
||||
( not PartialMatch and sibling.EqualsTree[Target]) then
|
||||
// v.appendelement(sibling)
|
||||
;
|
||||
|
||||
if Assigned( sibling.FirstChild) then
|
||||
DoFindAll( sibling.FirstChild, {v,} Target, PartialMatch);
|
||||
|
||||
sibling := sibling.NextSibling
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
// ================================================================================================
|
||||
// Get Number of Children
|
||||
// ================================================================================================
|
||||
function TAST.GetNumberofChildren: integer;
|
||||
var
|
||||
t: TAST;
|
||||
n: integer;
|
||||
|
||||
begin
|
||||
t := fDown;
|
||||
n := 0;
|
||||
|
||||
if Assigned(t) then
|
||||
begin
|
||||
INC(n);
|
||||
|
||||
while Assigned(t.fRight) do
|
||||
begin
|
||||
t := t.fRight;
|
||||
INC(n)
|
||||
end;
|
||||
end;
|
||||
|
||||
result := n
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Equals
|
||||
// ================================================================================================
|
||||
function TAST.GetEquals(Node: TAST): boolean;
|
||||
begin
|
||||
if Assigned(Node)
|
||||
then result := (Node.fAstText = fAstText) and (Node.fAstType = fAstType)
|
||||
else result := false
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Equals List
|
||||
// ================================================================================================
|
||||
function TAST.GetEqualsList(Node: TAST): boolean;
|
||||
var
|
||||
sibling: TAST;
|
||||
|
||||
begin
|
||||
result := false;
|
||||
|
||||
if Assigned(Node) then
|
||||
begin
|
||||
sibling := self;
|
||||
|
||||
while Assigned(sibling) and Assigned(Node) do
|
||||
begin
|
||||
// as a quick optimization, check roots firt
|
||||
if not sibling.Equals[Node] then
|
||||
break;
|
||||
|
||||
// if roots match, do full list match test on children
|
||||
if Assigned( sibling.FirstChild) then
|
||||
begin
|
||||
if not sibling.FirstChild.EqualsList[Node.FirstChild] then
|
||||
break
|
||||
end
|
||||
|
||||
// sibling has no kids, make sure Node doesn't either
|
||||
else if Assigned(Node.FirstChild) then
|
||||
break;
|
||||
|
||||
sibling := sibling .NextSibling;
|
||||
Node := Node .NextSibling;
|
||||
end;
|
||||
|
||||
if not Assigned(sibling) and not Assigned(Node) then
|
||||
result := true
|
||||
end;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Equals List Partial
|
||||
//
|
||||
// Is Node a subtree of this list ? The siblings of the root are NOT ignored.
|
||||
// ================================================================================================
|
||||
function TAST.GetEqualsListPartial(Node: TAST): boolean;
|
||||
var
|
||||
sibling: TAST;
|
||||
|
||||
begin
|
||||
result := false;
|
||||
|
||||
if Assigned(Node) then
|
||||
begin
|
||||
sibling := self;
|
||||
|
||||
while Assigned(sibling) and Assigned(Node) do
|
||||
begin
|
||||
// as a quick optimization, check roots firt
|
||||
if not sibling.Equals[Node] then
|
||||
break;
|
||||
|
||||
// if roots match, do partial list match test on children
|
||||
if Assigned( sibling.FirstChild) then
|
||||
if not sibling.FirstChild.EqualsListPartial[Node.FirstChild] then
|
||||
break
|
||||
end;
|
||||
|
||||
if not Assigned(sibling) and Assigned(Node)
|
||||
then result := false
|
||||
else result := true
|
||||
end;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Equals Tree
|
||||
//
|
||||
// Is the tree rooted at *self* equals to *Node* ?
|
||||
// The sibling of *self* are ignored.
|
||||
// ================================================================================================
|
||||
function TAST.GetEqualsTree(Node: TAST): boolean;
|
||||
begin
|
||||
result := false;
|
||||
|
||||
if Equals[Node] then
|
||||
begin
|
||||
// if roots match, do full list match test on children
|
||||
if Assigned(FirstChild) then
|
||||
begin
|
||||
if not FirstChild.EqualsList[Node.FirstChild] then
|
||||
exit;
|
||||
end
|
||||
|
||||
// No kids, make sure *Node* hasn't either
|
||||
else if Assigned(Node.FirstChild) then
|
||||
exit;
|
||||
end;
|
||||
|
||||
result := true
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Equals Tree Partial
|
||||
// ================================================================================================
|
||||
function TAST.GetEqualsTreePartial(Node: TAST): boolean;
|
||||
begin
|
||||
result := false;
|
||||
|
||||
if Equals[Node] then
|
||||
if Assigned(FirstChild) then
|
||||
if not FirstChild.EqualsListPartial[Node] then
|
||||
exit;
|
||||
|
||||
result := true
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Names
|
||||
// ================================================================================================
|
||||
function TAST.GetTokenNames: TStringList;
|
||||
begin
|
||||
result := TStringList.Create;
|
||||
result.AddStrings(fTokenNames);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Verbose
|
||||
// ================================================================================================
|
||||
procedure TAST.SetVerbose(Verbose: boolean; Names: TStringList);
|
||||
begin
|
||||
fVerbose := Verbose;
|
||||
fTokenNames.Clear;
|
||||
ftokenNames.AddStrings(Names);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// AddChild
|
||||
// ================================================================================================
|
||||
procedure TAST.AddChild(node: TAST);
|
||||
var
|
||||
n: TAST;
|
||||
|
||||
begin
|
||||
if Assigned(node) then
|
||||
begin
|
||||
n := fDown;
|
||||
|
||||
if Assigned(n) then
|
||||
begin
|
||||
while Assigned(n.fRight) do
|
||||
n := n.fRight;
|
||||
|
||||
n.fRight := node
|
||||
end
|
||||
|
||||
else
|
||||
fDown := node
|
||||
end;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Remove Children
|
||||
// ================================================================================================
|
||||
procedure TAST.RemoveChildren;
|
||||
begin
|
||||
fDown := nil
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,14 @@
|
||||
unit dpgrtl.astCommon;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.astBase;
|
||||
|
||||
type
|
||||
TastCommon = class( TAST)
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,349 @@
|
||||
// AST Support code shared by TreeParser and Parser.
|
||||
// We use delegation to share code (and have only one
|
||||
// bit of code to maintain) rather than subclassing
|
||||
// or superclassing (forces AST support code to be
|
||||
// loaded even when you don't want to do AST stuff).
|
||||
//
|
||||
// Typically, setASTNodeType is used to specify the
|
||||
// homogeneous type of node to create, but you can override
|
||||
// create to make heterogeneous nodes etc...
|
||||
|
||||
unit dpgrtl.astFactory;
|
||||
|
||||
interface
|
||||
uses
|
||||
Generics.Collections,
|
||||
dpgrtl.types,
|
||||
dpgrtl.astBase,
|
||||
dpgrtl.astPair;
|
||||
|
||||
type
|
||||
TTokenToASTMap = TDictionary<integer,TASTClass>;
|
||||
|
||||
TASTFactory = class
|
||||
protected
|
||||
// How to specify the classname to create for a particular
|
||||
// token type. Note that DPG allows you to say, for example,
|
||||
//
|
||||
// tokens
|
||||
// {
|
||||
// PLUS<AST=PLUSNode>;
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// and it tracks everything statically. #[PLUS] will make you
|
||||
// a PLUSNode w/o use of this table.
|
||||
//
|
||||
// For tokens that DPG cannot track statically like #[i],
|
||||
// you can use this table to map PLUS (Integer) -> PLUSNode (Class)
|
||||
// etc... DPG sets the class map from the tokens {...} section
|
||||
// via the ASTFactory(Hashtable) ctor in antlr.Parser.
|
||||
|
||||
fASTNodeTypeName : AnsiString;
|
||||
fASTNodeTypeClass : TASTClass;
|
||||
|
||||
fTokenToASTMap : TTokenToASTMap;
|
||||
|
||||
protected
|
||||
function GetASTClass( TokenType: integer): TASTClass;
|
||||
procedure SetASTClass( TokenType: integer; ASTClass: TASTClass);
|
||||
|
||||
public
|
||||
function CreateAST( TokenType: integer=TT_INVALID;
|
||||
TokenText: string = ''): TAST; overload;
|
||||
|
||||
function CreateAST( TokenType: integer;
|
||||
TokenText: string;
|
||||
ASTName : string) : TAST; overload;
|
||||
|
||||
function CreateAST( ASTName : string) : TAST; overload;
|
||||
|
||||
function CreateAST( AST : TAST) : TAST; overload;
|
||||
function CreateAST( Token : IToken) : TAST; overload;
|
||||
|
||||
function Clone( AST : TAST) : TAST;
|
||||
function CloneList( AST : TAST) : TAST;
|
||||
function CloneTree( AST : TAST) : TAST;
|
||||
|
||||
function Make( Nodes : array of TAST) : TAST;
|
||||
procedure MakeRoot( ASTPair : TASTPair;
|
||||
Root : TAST);
|
||||
|
||||
|
||||
public
|
||||
constructor Create( map: TTokenToASTMap);
|
||||
destructor Destroy; override;
|
||||
|
||||
public
|
||||
property ASTClass[t: integer] : TASTClass read GetASTClass
|
||||
write SetASTClass;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.RTTI,
|
||||
dpgrtl.astCommon,
|
||||
System.SysUtils;
|
||||
|
||||
{ TASTFactory }
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TASTFactory.Create(map: TTokenToASTMap);
|
||||
begin
|
||||
inherited Create;
|
||||
fTokenToASTMap := TTokenToASTMap.Create;
|
||||
|
||||
// SetTokenToASTMap(map);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Destructor
|
||||
// ================================================================================================
|
||||
destructor TASTFactory.Destroy;
|
||||
begin
|
||||
FreeAndNil(fTokenToASTMap);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
||||
// @@@: Interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Create AST (TokenType,TokenText)
|
||||
//
|
||||
// Create a new empty AST node. If the user did not specify an AST node type, then create a
|
||||
// default one: *TastCommon*
|
||||
// ================================================================================================
|
||||
function TASTFactory.CreateAST(TokenType: integer; TokenText: string): TAST;
|
||||
begin
|
||||
result := ASTClass[TokenType].Create;
|
||||
|
||||
if Assigned(result) then
|
||||
result.Initialize( TokenType, AnsiString(TokenText));
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Create AST (AST Class Name)
|
||||
// ================================================================================================
|
||||
function TASTFactory.CreateAST(ASTName: string): TAST;
|
||||
var
|
||||
ctx : TRttiContext;
|
||||
typ : TRttiType;
|
||||
|
||||
begin
|
||||
result := nil;
|
||||
ctx := TRttiContext.Create;
|
||||
typ := ctx.FindType(ASTName);
|
||||
|
||||
if Assigned(typ) then
|
||||
result := TASTClass(typ).Create;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Create AST
|
||||
// ================================================================================================
|
||||
function TASTFactory.CreateAST(TokenType: integer; TokenText, ASTName: string): TAST;
|
||||
begin
|
||||
result := CreateAST( ASTName);
|
||||
|
||||
if Assigned(result) then
|
||||
result.Initialize( TokenType, AnsiString(TokenText))
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Create AST
|
||||
// ================================================================================================
|
||||
function TASTFactory.CreateAST(AST: TAST): TAST;
|
||||
begin
|
||||
result := nil;
|
||||
|
||||
if Assigned(AST) then
|
||||
result := CreateAST(AST.ClassName);
|
||||
|
||||
if Assigned(result) then
|
||||
result.Initialize( AST.AstType, AST.AstText);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Create AST
|
||||
// ================================================================================================
|
||||
function TASTFactory.CreateAST(Token: IToken): TAST;
|
||||
begin
|
||||
result := nil;
|
||||
|
||||
if Assigned(Token) then
|
||||
result := CreateAST( Token.TokenType, string(Token.TokenText))
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clone
|
||||
// ================================================================================================
|
||||
function TASTFactory.Clone( AST: TAST) : TAST;
|
||||
begin
|
||||
result := nil;
|
||||
|
||||
if Assigned(AST) then
|
||||
result := CreateAST(AST);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clone List
|
||||
//
|
||||
// Duplicate a tree including siblings of root.
|
||||
// ================================================================================================
|
||||
function TASTFactory.CloneList( AST: TAST): TAST;
|
||||
var
|
||||
nt: TAST;
|
||||
|
||||
begin
|
||||
result := CloneTree(AST);
|
||||
nt := result;
|
||||
|
||||
while Assigned(AST) do
|
||||
begin
|
||||
AST := AST.NextSibling;
|
||||
|
||||
nt.NextSibling := CloneTree(AST);
|
||||
nt := nt.NextSibling;
|
||||
end;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clone Tree
|
||||
//
|
||||
// Duplicate a tree, assuming this is a root node of a tree.
|
||||
// Duplicate that node and what's below; ignore siblings of a root node.
|
||||
// ================================================================================================
|
||||
function TASTFactory.CloneTree( AST: TAST): TAST;
|
||||
begin
|
||||
result := Clone(AST);
|
||||
|
||||
if Assigned(result) then
|
||||
result.FirstChild := CloneList( AST.FirstChild)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Make
|
||||
//
|
||||
// Make a tree from a list of nodes. The first element in the array is the root.
|
||||
// If the root is null, then the tree is a simple list not a tree.
|
||||
// Handles null children nodes correctly.
|
||||
//
|
||||
// For example, build(a, b, null, c) yields tree (a b c).
|
||||
// build(null,a,b) yields tree (nil a b).
|
||||
// ================================================================================================
|
||||
function TASTFactory.Make(Nodes: array of TAST): TAST;
|
||||
var
|
||||
i : integer;
|
||||
root : TAST;
|
||||
tail : TAST;
|
||||
|
||||
begin
|
||||
result := nil;
|
||||
|
||||
if Length(Nodes) > 0 then
|
||||
begin
|
||||
root := Nodes[Low(Nodes)];
|
||||
tail := nil;
|
||||
|
||||
if Assigned(root) then
|
||||
root.FirstChild := nil;
|
||||
|
||||
// link in children
|
||||
for i:=Low(Nodes)+1 to High(Nodes) do
|
||||
begin
|
||||
// ignore nil nodes
|
||||
if Nodes[i] = nil then
|
||||
continue;
|
||||
|
||||
if not Assigned(root) then
|
||||
begin
|
||||
root := nodes[i];
|
||||
tail := nodes[i];
|
||||
end
|
||||
|
||||
else if not Assigned(tail) then
|
||||
begin
|
||||
root.FirstChild := Nodes[i];
|
||||
tail := root.FirstChild;
|
||||
end
|
||||
|
||||
else begin
|
||||
tail.NextSibling:= Nodes[i];
|
||||
tail := tail.NextSibling;
|
||||
end;
|
||||
|
||||
while Assigned(tail.NextSibling) do
|
||||
tail := tail.NextSibling;
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Make root
|
||||
// ================================================================================================
|
||||
procedure TASTFactory.MakeRoot(ASTPair: TASTPair; Root: TAST);
|
||||
begin
|
||||
if Assigned(Root) then
|
||||
begin
|
||||
Root.AddChild(ASTPair.Root);
|
||||
|
||||
ASTPair.Child := ASTPair.Root;
|
||||
ASTPair.AdvanceChildToEnd;
|
||||
ASTPair.Root := Root;
|
||||
end
|
||||
end;
|
||||
|
||||
// @@@: Property handlers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Property handlers
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get the AST class that assigned to a token type
|
||||
// ================================================================================================
|
||||
function TASTFactory.GetASTClass(TokenType: integer): TASTClass;
|
||||
begin
|
||||
result := nil;
|
||||
|
||||
if Assigned( fTokenToASTMap) then
|
||||
fTokenToASTMap.TryGetValue( TokenType, result);
|
||||
|
||||
if not Assigned(result) then
|
||||
result := fASTNodeTypeClass;
|
||||
|
||||
if not Assigned(result) then
|
||||
result := TastCommon;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Assign an AST class to a token type
|
||||
// ================================================================================================
|
||||
procedure TASTFactory.SetASTClass(TokenType: integer; ASTClass: TASTClass);
|
||||
begin
|
||||
if Assigned( fTokenToASTMap) then
|
||||
begin
|
||||
if fTokenToASTMap.ContainsKey(TokenType) then
|
||||
fTokenToASTMap.Remove(TokenType);
|
||||
|
||||
if Assigned(ASTClass) then
|
||||
fTokenToASTMap.Add(TokenType,ASTClass)
|
||||
end
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,64 @@
|
||||
unit dpgrtl.astPair;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.astBase;
|
||||
|
||||
type
|
||||
TASTPair = class
|
||||
public
|
||||
Root : TAST;
|
||||
Child : TAST;
|
||||
|
||||
public
|
||||
procedure AdvanceChildToEnd;
|
||||
function Clone: TASTPair;
|
||||
function ToString: string; override;
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TASTPair }
|
||||
|
||||
// ================================================================================================
|
||||
// Advance Child To End
|
||||
// ================================================================================================
|
||||
procedure TASTPair.AdvanceChildToEnd;
|
||||
begin
|
||||
if Assigned(Child) then
|
||||
while Assigned( Child.NextSibling) do
|
||||
Child := Child.NextSibling
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clone
|
||||
// ================================================================================================
|
||||
function TASTPair.Clone: TASTPair;
|
||||
begin
|
||||
result := TASTPair.Create;
|
||||
result.Root := Root;
|
||||
result.Child := Child;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// As String
|
||||
// ================================================================================================
|
||||
function TASTPair.ToString: string;
|
||||
var
|
||||
r: string;
|
||||
c: string;
|
||||
|
||||
begin
|
||||
if Assigned(Root)
|
||||
then r := Root.ToString
|
||||
else r := 'nil';
|
||||
|
||||
if Assigned(Child)
|
||||
then c := Child.ToString
|
||||
else c := 'nil';
|
||||
|
||||
result := '[' + r + ',' + c + ']'
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,156 @@
|
||||
// TODO: jo lenne cache-elni az LA(x) karaktereket...
|
||||
|
||||
unit dpgrtl.charbuffer;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
dpgrtl.types,
|
||||
dpgrtl.inputbuffer,
|
||||
dpgrtl.charqueue;
|
||||
|
||||
type
|
||||
TCharBuffer = class( TInputBuffer, IInputBuffer, ICharBuffer)
|
||||
protected
|
||||
fStream : TStream;
|
||||
fQueue : TCharQueue;
|
||||
|
||||
protected
|
||||
function GetNext: AnsiChar;
|
||||
procedure Fill( Amount: integer);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// TInputBuffer overrides
|
||||
// ------------------------------------------------------------
|
||||
protected
|
||||
procedure Remove( ACount: integer); override;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// ICharBuffer
|
||||
// ------------------------------------------------------------
|
||||
protected
|
||||
function LA( i: integer): AnsiChar;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ------------------------------------------------------------
|
||||
public
|
||||
constructor Create( AStream: TStream);
|
||||
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TCharBuffer }
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TCharBuffer.Create(AStream: TStream);
|
||||
begin
|
||||
inherited Create;
|
||||
fStream := AStream
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// After Destruction
|
||||
// ================================================================================================
|
||||
procedure TCharBuffer.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fMarkerCount := 0;
|
||||
fMarkerOffset := 0;
|
||||
fNumToConsume := 0;
|
||||
|
||||
fQueue := TCharQueue.Create
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TCharBuffer.BeforeDestruction;
|
||||
begin
|
||||
fQueue.Free;
|
||||
inherited
|
||||
end;
|
||||
|
||||
// @@@: Interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// LA
|
||||
//
|
||||
// Ensures that the 'fQueue' object holds sufficient characters, and gets the 'i'th Look Ahead
|
||||
// character from the 'fQueue'.
|
||||
// ================================================================================================
|
||||
function TCharBuffer.LA(i: integer): AnsiChar;
|
||||
begin
|
||||
Fill(i);
|
||||
result := fQueue.Items[fMarkerOffset +i]
|
||||
end;
|
||||
|
||||
// @@@: Internals +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Internals
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Next
|
||||
// ================================================================================================
|
||||
function TCharBuffer.GetNext: AnsiChar;
|
||||
begin
|
||||
if fStream.Read( result, 1) <> 1 then
|
||||
result := #0
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Fill
|
||||
// ================================================================================================
|
||||
procedure TCharBuffer.Fill(Amount: integer);
|
||||
begin
|
||||
SyncConsume;
|
||||
|
||||
while fQueue.Count < (Amount +fMarkerOffset) do
|
||||
fQueue.Add(GetNext)
|
||||
end;
|
||||
|
||||
// @@@: Overrides +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Overrides
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Remove
|
||||
// ================================================================================================
|
||||
procedure TCharBuffer.Remove(ACount: integer);
|
||||
begin
|
||||
fQueue.Remove(ACount)
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,291 @@
|
||||
unit dpgrtl.charqueue;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
TCharQueue = class( TInterfacedObject)
|
||||
private
|
||||
fBlockLog : integer; // log2 of block size
|
||||
fBlockSize : integer; // block size
|
||||
|
||||
fOffset : integer; // logical start of the vector
|
||||
fCount : integer; // items in a vector
|
||||
fArray : TCharMatrix; // data
|
||||
|
||||
private
|
||||
procedure Expand( i: integer);
|
||||
|
||||
protected
|
||||
function GetItem( i:integer): AnsiChar;
|
||||
procedure SetItem( i:integer; Value:AnsiChar);
|
||||
|
||||
public
|
||||
procedure Clear;
|
||||
procedure Add( Value : AnsiChar);
|
||||
procedure Remove( ACount: integer);
|
||||
|
||||
public
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
|
||||
public
|
||||
property Count : integer read fCount;
|
||||
property Items[i:integer] : AnsiChar read GetItem write SetItem;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.Math,
|
||||
System.SysUtils;
|
||||
|
||||
{ TCharQueue }
|
||||
|
||||
// @@@: construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TCharQueue.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fBlockLog := trunc( log2( 4096));
|
||||
fBlockSize := trunc( IntPower(2, fBlockLog));
|
||||
|
||||
fArray := nil;
|
||||
fOffset := 0;
|
||||
fCount := 0;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TCharQueue.BeforeDestruction;
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
Clear;
|
||||
|
||||
for i:=Low(fArray) to High(fArray) do
|
||||
fArray[i] := nil;
|
||||
|
||||
fArray := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// @@@: Interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Add
|
||||
// ================================================================================================
|
||||
procedure TCharQueue.Add(Value: AnsiChar);
|
||||
begin
|
||||
Items[ fCount +1] := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Remove
|
||||
//
|
||||
// Removes 'Count' items from the beginning of the queue. If the 'Count' is bigger than the
|
||||
// count then simply clear the Queue.
|
||||
// ================================================================================================
|
||||
procedure TCharQueue.Remove( ACount: integer);
|
||||
var
|
||||
tmp: TCharMatrix;
|
||||
i : integer;
|
||||
|
||||
begin
|
||||
if ACount > 0 then
|
||||
begin
|
||||
// ------------------------------------------------------------
|
||||
// if the removable item count > than the item count, then
|
||||
// simply clear the queue...
|
||||
// ------------------------------------------------------------
|
||||
if ACount > fCount then
|
||||
Clear
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// ...else calculate the new offset and count values. If the
|
||||
// one or more blocks in the vector beginning is freed, then
|
||||
// move these blocks to the end of the vector.
|
||||
// ------------------------------------------------------------
|
||||
else begin
|
||||
INC( fOffset, ACount);
|
||||
DEC( fCount, ACount);
|
||||
|
||||
SetLength( tmp, 1);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Well, not so efficient, but simple
|
||||
// ---------------------------------------------------------
|
||||
while fOffset > fBlockSize -1 do
|
||||
begin
|
||||
tmp[0] := fArray[0];
|
||||
|
||||
// --------------------------------------------
|
||||
// clear the free block
|
||||
// --------------------------------------------
|
||||
for i:=0 to High(tmp[0]) do
|
||||
tmp[0,i] := #0;
|
||||
|
||||
// --------------------------------------------
|
||||
// shift blocks down
|
||||
// --------------------------------------------
|
||||
for i:=0 to High(fArray)-1 do
|
||||
fArray[i] := fArray[i+1];
|
||||
|
||||
// --------------------------------------------
|
||||
// set the vector's last block
|
||||
// --------------------------------------------
|
||||
fArray[High(fArray)] := tmp[0];
|
||||
|
||||
DEC( fOffset, fBlockSize)
|
||||
end;
|
||||
|
||||
tmp := nil
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clear
|
||||
//
|
||||
// This is a real pain in the ass. I'm not in the mood to optimize it.
|
||||
// ================================================================================================
|
||||
procedure TCharQueue.Clear;
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
for i:=1 to fCount do
|
||||
Items[i] := #0;
|
||||
|
||||
fOffset := 0;
|
||||
fCount := 0;
|
||||
end;
|
||||
|
||||
|
||||
// @@@: Property Handlers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Property Handlers
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Item
|
||||
//
|
||||
// Get the item specified by it's index. If the index less than 1 or bigger than the size of
|
||||
// the queue, an ERangeError exception will be generated.
|
||||
// ================================================================================================
|
||||
function TCharQueue.GetItem(i: integer): AnsiChar;
|
||||
var
|
||||
block: integer;
|
||||
index: integer;
|
||||
|
||||
begin
|
||||
// -------------------------------------------------------------------------
|
||||
// Check for valid index value.
|
||||
// -------------------------------------------------------------------------
|
||||
if i > fCount then raise ERangeError.CreateFmt( 'Index "%d" is too big', [i]);
|
||||
if i < 1 then raise ERangeError.CreateFmt( 'Index is less than 1', []);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Now process the request.
|
||||
// -------------------------------------------------------------------------
|
||||
block := (i -1 +fOffset) shr fBlockLog;
|
||||
index := (i -1 +fOffset) and (fBlockSize -1);
|
||||
|
||||
result := fArray[block,index];
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Item
|
||||
//
|
||||
// Set the item specified by it's index. If the the index bigger than the count of the Queue
|
||||
// then the Queue will be resized to hold this data. If the index less than 1 an ERangeError
|
||||
// exception will be generated.
|
||||
// ================================================================================================
|
||||
procedure TCharQueue.SetItem(i: integer; Value: AnsiChar);
|
||||
var
|
||||
block: integer;
|
||||
index: integer;
|
||||
|
||||
begin
|
||||
// -------------------------------------------------------------------------
|
||||
// Check for valid index value.
|
||||
// -------------------------------------------------------------------------
|
||||
if i < 1 then raise ERangeError.CreateFmt( 'Index is less than 1', []);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// If the index bigger than the size of the Queue then expand the Queue.
|
||||
// -------------------------------------------------------------------------
|
||||
if i > fCount then
|
||||
begin
|
||||
Expand(i);
|
||||
fCount := i;
|
||||
end;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Now process the request.
|
||||
// -------------------------------------------------------------------------
|
||||
block := (i -1 +fOffset) shr fBlockLog;
|
||||
index := (i -1 +fOffset) and (fBlockSize -1);
|
||||
|
||||
fArray[block,index] := Value
|
||||
end;
|
||||
|
||||
// @@@: Internals +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Internals
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Expand
|
||||
//
|
||||
// Expands the Queue. The size of expanding is always fBlockSize*n.
|
||||
// ================================================================================================
|
||||
procedure TCharQueue.Expand(i: integer);
|
||||
var
|
||||
hi: integer;
|
||||
bn: integer;
|
||||
j : integer;
|
||||
|
||||
begin
|
||||
if (i-1)+fOffset >= (High(fArray)+1) * fBlockSize then
|
||||
begin
|
||||
hi := High(fArray) +1;
|
||||
bn := (i-1+fOffset) shr fBlockLog;
|
||||
|
||||
SetLength( fArray, bn+1);
|
||||
|
||||
for j:=hi to bn do
|
||||
SetLength( fArray[j], fBlockSize);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,258 @@
|
||||
unit dpgrtl.exception;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
System.SysUtils;
|
||||
|
||||
type
|
||||
EException = class(Exception)
|
||||
strict protected
|
||||
fFileName : string;
|
||||
fLine : integer;
|
||||
fColumn : integer;
|
||||
|
||||
public
|
||||
constructor Create( AFileName : string;
|
||||
ALine : integer;
|
||||
AColumn : integer);
|
||||
|
||||
public
|
||||
property FileName : string read fFileName;
|
||||
property Line : integer read fLine;
|
||||
property Column : integer read fColumn;
|
||||
|
||||
end;
|
||||
|
||||
EMismatchedChar = class( EException)
|
||||
strict protected
|
||||
fCharSet : TCharSet;
|
||||
fString : AnsiString;
|
||||
|
||||
fFoundChar : AnsiChar;
|
||||
fFoundString: AnsiString;
|
||||
|
||||
fInverted : boolean;
|
||||
|
||||
public
|
||||
function ToString: string; override;
|
||||
|
||||
public
|
||||
constructor Create( AFoundChar : AnsiChar;
|
||||
ACharSet : TCharSet;
|
||||
AFileName : string;
|
||||
ALine : integer;
|
||||
AColumn : integer;
|
||||
AInverted : boolean=false); overload;
|
||||
|
||||
constructor Create( AFoundString : AnsiString;
|
||||
AExpectedString : AnsiString;
|
||||
AFileName : string;
|
||||
ALine : integer;
|
||||
AColumn : integer); overload;
|
||||
|
||||
|
||||
|
||||
public
|
||||
property FoundChar : AnsiChar read fFoundChar;
|
||||
property FoundString : AnsiString read fFoundString;
|
||||
property CharSet : TCharSet read fCharSet;
|
||||
property Str : AnsiString read fString;
|
||||
property Inverted : boolean read fInverted;
|
||||
end;
|
||||
|
||||
EMismatchedToken = class (EException)
|
||||
strict protected
|
||||
fToken : IToken;
|
||||
fTokenSet : TByteSet;
|
||||
fFoundToken : IToken;
|
||||
fInverted : boolean;
|
||||
|
||||
public
|
||||
constructor Create( AFoundToken : IToken;
|
||||
ATokenType : byte;
|
||||
AFileName : string;
|
||||
AInverted : boolean=false); overload;
|
||||
|
||||
constructor Create( AFoundToken : IToken;
|
||||
ATokenSet : TByteSet;
|
||||
AFileName : string;
|
||||
AInverted : boolean=false); overload;
|
||||
|
||||
procedure BeforeDestruction; override;
|
||||
|
||||
public
|
||||
property FoundToken : IToken read fFoundToken;
|
||||
property TokenSet : TByteSet read fTokenSet;
|
||||
property Inverted : boolean read fInverted;
|
||||
end;
|
||||
|
||||
ESemantic = class (EException)
|
||||
strict protected
|
||||
fAssert : AnsiString;
|
||||
|
||||
public
|
||||
constructor Create( ASemPred : AnsiString;
|
||||
AFileName : string;
|
||||
ALine : integer=0;
|
||||
AColumn : integer=0);
|
||||
|
||||
public
|
||||
property Assert: AnsiString read fAssert;
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ EException }
|
||||
|
||||
// @@@: EException ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// EException
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// constructor
|
||||
// ================================================================================================
|
||||
constructor EException.Create(AFileName: string; ALine, AColumn: integer);
|
||||
begin
|
||||
fFileName := AFileName;
|
||||
fLine := ALine;
|
||||
fColumn := AColumn;
|
||||
end;
|
||||
|
||||
{ EMismatchedChar }
|
||||
|
||||
// @@@: EMismatchedChar +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// EMismatchedChar
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// constructor([char..char])
|
||||
// ================================================================================================
|
||||
constructor EMismatchedChar.Create( AFoundChar : AnsiChar;
|
||||
ACharSet : TCharSet;
|
||||
AFileName : string;
|
||||
ALine : integer;
|
||||
AColumn : integer;
|
||||
AInverted : boolean=false);
|
||||
begin
|
||||
inherited Create( AFileName, ALine, AColumn);
|
||||
|
||||
fCharSet := ACharSet;
|
||||
fString := '';
|
||||
|
||||
fFoundChar := AFoundChar;
|
||||
fFoundString := '';
|
||||
|
||||
fInverted := AInverted
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// constructor(string)
|
||||
// ================================================================================================
|
||||
constructor EMismatchedChar.Create( AFoundString : AnsiString;
|
||||
AExpectedString : AnsiString;
|
||||
AFileName : string;
|
||||
ALine : integer;
|
||||
AColumn : integer);
|
||||
begin
|
||||
inherited Create( AFileName, ALine, AColumn);
|
||||
|
||||
fCharSet := [];
|
||||
fString := AExpectedString;
|
||||
|
||||
fFoundChar := #0;
|
||||
fFoundString := AFoundString;
|
||||
|
||||
fInverted := false
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// ToString
|
||||
// ================================================================================================
|
||||
function EMismatchedChar.ToString: string;
|
||||
begin
|
||||
result := '?'
|
||||
end;
|
||||
|
||||
{ EMismatchedToken }
|
||||
|
||||
// @@@: EMismatchedToken ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// EMismatchedToken
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// constructor
|
||||
// ================================================================================================
|
||||
constructor EMismatchedToken.Create(AFoundToken : IToken;
|
||||
ATokenType : byte;
|
||||
AFileName : string;
|
||||
AInverted : boolean=false);
|
||||
begin
|
||||
inherited Create(AFileName, AFoundToken.TokenLine, AFoundToken.TokenColumn);
|
||||
|
||||
fFoundToken := AFoundToken;
|
||||
fTokenSet := [ATokenType];
|
||||
fInverted := AInverted
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// constructor
|
||||
// ================================================================================================
|
||||
constructor EMismatchedToken.Create(AFoundToken : IToken;
|
||||
ATokenSet : TByteSet;
|
||||
AFileName : string;
|
||||
AInverted : boolean=false);
|
||||
begin
|
||||
inherited Create(AFileName, AFoundToken.TokenLine, AFoundToken.TokenColumn);
|
||||
|
||||
fFoundToken := AFoundToken;
|
||||
fTokenSet := ATokenSet;
|
||||
fInverted := AInverted
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure EMismatchedToken.BeforeDestruction;
|
||||
begin
|
||||
fFoundToken := nil;
|
||||
inherited
|
||||
end;
|
||||
|
||||
{ ESemantic }
|
||||
|
||||
// @@@: ESemantic +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// ESemantic
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// constructor
|
||||
// ================================================================================================
|
||||
constructor ESemantic.Create(ASemPred: AnsiString; AFileName: string; ALine, AColumn: integer);
|
||||
begin
|
||||
inherited Create( AFileName, ALine, AColumn);
|
||||
fAssert := ASemPred
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,123 @@
|
||||
unit dpgrtl.inputbuffer;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
TInputBuffer = class( TInterfacedObject, IInputBuffer)
|
||||
protected
|
||||
fMarkerCount : integer;
|
||||
fMarkerOffset : integer;
|
||||
fNumToConsume : integer;
|
||||
|
||||
protected
|
||||
procedure Remove( Num: integer); virtual; abstract;
|
||||
procedure SyncConsume; inline;
|
||||
|
||||
protected
|
||||
function GetMarked: boolean; inline;
|
||||
|
||||
procedure Consume; inline;
|
||||
procedure Commit; inline;
|
||||
|
||||
function Mark: integer;
|
||||
procedure Rewind( Value: integer);
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
{ TInputBuffer }
|
||||
|
||||
// @@@: IInputBuffer implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IInputBuffer implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Mark
|
||||
//
|
||||
// Returns an integer marker theh can be used to rewind the buffer to its current state.
|
||||
// ================================================================================================
|
||||
function TInputBuffer.Mark: integer;
|
||||
begin
|
||||
SyncConsume;
|
||||
INC( fMarkerCount);
|
||||
|
||||
result := fMarkerOffset
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Consume
|
||||
//
|
||||
// Mark another input item for deferred consumption.
|
||||
// ================================================================================================
|
||||
procedure TInputBuffer.Consume;
|
||||
begin
|
||||
INC( fNumToConsume);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Commit
|
||||
//
|
||||
// This method updates the state of the input buffer so that the text matched since the most
|
||||
// recent Mark() is no longer held by the buffer. So, you either do a mark/rewind for failed
|
||||
// predicate or mark/commit to keep on parsing without rewinding the input.
|
||||
// ================================================================================================
|
||||
procedure TInputBuffer.Commit;
|
||||
begin
|
||||
if fMarkerCount > 0 then
|
||||
DEC( fMarkerCount)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Rewind
|
||||
//
|
||||
// Rewind the character buffer to a marker. 'Value' marker returned previously from mark.
|
||||
// ================================================================================================
|
||||
procedure TInputBuffer.Rewind(Value: integer);
|
||||
begin
|
||||
SyncConsume;
|
||||
|
||||
fMarkerOffset := Value;
|
||||
DEC( fMarkerCount)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// GetMarked
|
||||
// ================================================================================================
|
||||
function TInputBuffer.GetMarked: boolean;
|
||||
begin
|
||||
result := fMarkerCount <> 0
|
||||
end;
|
||||
|
||||
// @@@: Internals +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Internals
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Sync Consume
|
||||
// ================================================================================================
|
||||
procedure TInputBuffer.SyncConsume;
|
||||
begin
|
||||
if fNumToConsume > 0 then
|
||||
begin
|
||||
if fMarkerCount > 0
|
||||
then INC( fMarkerOffset, fNumToConsume)
|
||||
else Remove( fNumToConsume);
|
||||
|
||||
fNumToConsume := 0
|
||||
end
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,593 @@
|
||||
unit dpgrtl.lexer;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.SysUtils,
|
||||
System.AnsiStrings,
|
||||
dpgrtl.types,
|
||||
dpgrtl.token,
|
||||
dpgrtl.stringmap,
|
||||
dpgrtl.lexerstate;
|
||||
|
||||
type
|
||||
TLexer = class( TInterfacedObject, ITokenStream)
|
||||
protected
|
||||
TokenText : AnsiString;
|
||||
|
||||
fTokenClass : TTokenClass;
|
||||
fLexerState : ILexerState;
|
||||
fLiterals : TStringMap;
|
||||
|
||||
fCaseSensitive : boolean;
|
||||
fSaveConsumedInput: boolean;
|
||||
|
||||
fReturnToken : IToken;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Property Handlers
|
||||
// ----------------------------------------------------------------------
|
||||
private
|
||||
function GetTokenClass: TTokenClass;
|
||||
procedure SetTokenClass( AClass: TTokenClass);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// ITokenStream
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function NextToken: IToken; virtual; abstract;
|
||||
|
||||
protected
|
||||
// -------------------------------------------------------------------
|
||||
procedure Append( AChar : AnsiChar); overload;
|
||||
procedure Append( AString : AnsiString); overload;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
procedure Consume;
|
||||
procedure ConsumeUntil( AChar : AnsiChar); overload;
|
||||
procedure ConsumeUntil( ASet : TCharSet); overload;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
procedure MatchNot( AChar : AnsiChar);
|
||||
|
||||
procedure Match( AChar : AnsiChar); overload;
|
||||
procedure Match( ASet : TCharSet); overload;
|
||||
procedure Match( AString : AnsiString); overload;
|
||||
procedure Match( AChar1 : AnsiChar;
|
||||
AChar2 : AnsiChar); overload;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
function TestLiteral( AType : integer): integer; overload;
|
||||
function TestLiteral( AText : AnsiString;
|
||||
AType : integer): integer; overload;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
procedure Tab; virtual;
|
||||
procedure UponEof; virtual;
|
||||
procedure Initialize; virtual;
|
||||
procedure ReportError( e: Exception); virtual;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
function LA(i:integer): AnsiChar;
|
||||
function Mark: integer;
|
||||
procedure Rewind( Pos: integer);
|
||||
procedure Commit;
|
||||
procedure NewLine;
|
||||
procedure ResetText;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
function MakeToken( ATokenType : integer;
|
||||
ATokenText : AnsiString=''): IToken;
|
||||
|
||||
public
|
||||
constructor Create( ABuffer: ICharBuffer); overload;
|
||||
constructor Create( AState : ILexerState); overload;
|
||||
constructor Create( AStream: TStream); overload;
|
||||
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
|
||||
public
|
||||
property SaveConsumedInput : boolean read fSaveConsumedInput
|
||||
write fSaveConsumedInput;
|
||||
|
||||
property CaseSensitive : boolean read fCaseSensitive
|
||||
write fCaseSensitive;
|
||||
|
||||
property TokenClass : TTokenClass read GetTokenClass
|
||||
write SetTokenClass;
|
||||
|
||||
property InputState : ILexerState read fLexerState
|
||||
write fLexerState;
|
||||
|
||||
property ReturnToken : IToken read fReturnToken
|
||||
write fReturnToken;
|
||||
end;
|
||||
|
||||
TLexerClass = class of TLexer;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpgrtl.exception;
|
||||
|
||||
{ TLexer }
|
||||
|
||||
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor(ICharBuffer)
|
||||
// ================================================================================================
|
||||
constructor TLexer.Create( ABuffer: ICharBuffer);
|
||||
begin
|
||||
inherited Create;
|
||||
fLexerState := TLexerState.Create( ABuffer);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(ILexerState)
|
||||
// ================================================================================================
|
||||
constructor TLexer.Create( AState: ILexerState);
|
||||
begin
|
||||
inherited Create;
|
||||
fLexerState := AState
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(TStream)
|
||||
// ================================================================================================
|
||||
constructor TLexer.Create( AStream: TStream);
|
||||
begin
|
||||
inherited Create;
|
||||
fLexerState := TLexerState.Create( AStream)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TLexer.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fLiterals := TStringMap.Create;
|
||||
fLiterals.CaseSensitive := true;
|
||||
fCaseSensitive := true;
|
||||
fSaveConsumedInput := true;
|
||||
|
||||
Initialize;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TLexer.BeforeDestruction;
|
||||
begin
|
||||
fLexerState := nil;
|
||||
fLiterals.Free;
|
||||
|
||||
inherited
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// @@@: Property Handlers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Property Handlers
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Token Class
|
||||
// ================================================================================================
|
||||
function TLexer.GetTokenClass: TTokenClass;
|
||||
begin
|
||||
if fTokenClass = nil
|
||||
then result := TToken
|
||||
else result := fTokenClass
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Token Class
|
||||
// ================================================================================================
|
||||
procedure TLexer.SetTokenClass( AClass: TTokenClass);
|
||||
begin
|
||||
fTokenClass := AClass
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// @@@: Internals +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Internals
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Append(Char)
|
||||
// ================================================================================================
|
||||
procedure TLexer.Append( AChar: AnsiChar);
|
||||
begin
|
||||
if fSaveConsumedInput then
|
||||
TokenText := TokenText +AChar
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Append(String)
|
||||
// ================================================================================================
|
||||
procedure TLexer.Append( AString: AnsiString);
|
||||
begin
|
||||
if fSaveConsumedInput then
|
||||
TokenText := TokenText +AString
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Consume
|
||||
// ================================================================================================
|
||||
procedure TLexer.Consume;
|
||||
var
|
||||
chr: AnsiChar;
|
||||
|
||||
begin
|
||||
chr := LA(1);
|
||||
|
||||
if fLexerState.Guessing = 0 then
|
||||
begin
|
||||
Append(chr);
|
||||
|
||||
if chr = #9
|
||||
then TAB
|
||||
else fLexerState.Column := fLexerState.Column +1;
|
||||
end;
|
||||
|
||||
fLexerState.InputBuffer.Consume
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// ComsumeUntil(Char)
|
||||
// ================================================================================================
|
||||
procedure TLexer.ConsumeUntil(AChar: AnsiChar);
|
||||
var
|
||||
chr: AnsiChar;
|
||||
|
||||
begin
|
||||
chr := LA(1);
|
||||
|
||||
while (chr <> EOF_CHAR) and (chr <> AChar) do
|
||||
begin
|
||||
Consume;
|
||||
chr := LA(1)
|
||||
end
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// ConsumeUntil(Set)
|
||||
// ================================================================================================
|
||||
procedure TLexer.ConsumeUntil(ASet: TCharSet);
|
||||
var
|
||||
chr: AnsiChar;
|
||||
|
||||
begin
|
||||
chr := LA(1);
|
||||
|
||||
while (chr <> EOF_CHAR) and not(chr in ASet) do
|
||||
begin
|
||||
Consume;
|
||||
chr := LA(1)
|
||||
end
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Match Not(Char)
|
||||
// ================================================================================================
|
||||
procedure TLexer.MatchNot(AChar: AnsiChar);
|
||||
var
|
||||
chr : AnsiChar;
|
||||
la1 : AnsiChar;
|
||||
|
||||
begin
|
||||
if not fCaseSensitive then
|
||||
begin
|
||||
chr := UpCase( AChar);
|
||||
la1 := UpCase( LA(1));
|
||||
end
|
||||
|
||||
else begin
|
||||
chr := AChar;
|
||||
la1 := LA(1);
|
||||
end;
|
||||
|
||||
if la1 = chr then
|
||||
Raise EMismatchedChar.Create( LA(1),
|
||||
[AChar],
|
||||
fLexerState.FileName,
|
||||
fLexerState.Line,
|
||||
fLexerState.Column,
|
||||
true)
|
||||
else
|
||||
Consume
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Match(Char)
|
||||
// ================================================================================================
|
||||
procedure TLexer.Match(AChar: AnsiChar);
|
||||
var
|
||||
chr : AnsiChar;
|
||||
la1 : AnsiChar;
|
||||
|
||||
begin
|
||||
if not fCaseSensitive then
|
||||
begin
|
||||
chr := UpCase( AChar);
|
||||
la1 := UpCase( LA(1));
|
||||
end
|
||||
|
||||
else begin
|
||||
chr := AChar;
|
||||
la1 := LA(1);
|
||||
end;
|
||||
|
||||
if la1 <> chr then
|
||||
Raise EMismatchedChar.Create( LA(1),
|
||||
[AChar],
|
||||
fLexerState.FileName,
|
||||
fLexerState.Line,
|
||||
fLexerState.Column,
|
||||
false)
|
||||
else
|
||||
Consume
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Match(CharSet)
|
||||
// ================================================================================================
|
||||
procedure TLexer.Match(ASet: TCharSet);
|
||||
var
|
||||
la1: AnsiChar;
|
||||
|
||||
begin
|
||||
la1 := LA(1);
|
||||
|
||||
if not (la1 in ASet) then
|
||||
Raise EMismatchedChar.Create( la1,
|
||||
ASet,
|
||||
fLexerState.FileName,
|
||||
fLexerState.Line,
|
||||
fLexerState.Column,
|
||||
false)
|
||||
else
|
||||
Consume
|
||||
end;
|
||||
|
||||
|
||||
// ================================================================================================
|
||||
// Match(Char..Char)
|
||||
// ================================================================================================
|
||||
procedure TLexer.Match(AChar1, AChar2: AnsiChar);
|
||||
var
|
||||
chr1: AnsiChar;
|
||||
chr2: AnsiChar;
|
||||
la1 : AnsiChar;
|
||||
|
||||
begin
|
||||
if not fCaseSensitive then
|
||||
begin
|
||||
chr1 := UpCase( AChar1);
|
||||
chr2 := UpCase( AChar2);
|
||||
la1 := UpCase( LA(1));
|
||||
end
|
||||
|
||||
else begin
|
||||
chr1 := AChar1;
|
||||
chr2 := AChar2;
|
||||
la1 := LA(1);
|
||||
end;
|
||||
|
||||
if not (la1 in [chr1..chr2]) then
|
||||
Raise EMismatchedChar.Create( la1,
|
||||
[chr1..chr2],
|
||||
fLexerState.FileName,
|
||||
fLexerState.Line,
|
||||
fLexerState.Column,
|
||||
false)
|
||||
else
|
||||
Consume
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Match(string)
|
||||
// ================================================================================================
|
||||
procedure TLexer.Match(AString: AnsiString);
|
||||
var
|
||||
la1 : AnsiChar;
|
||||
s : AnsiString;
|
||||
str : AnsiString;
|
||||
len : integer;
|
||||
i : integer;
|
||||
|
||||
begin
|
||||
if not fCaseSensitive
|
||||
then str := AnsiUpperCase( AString)
|
||||
else str := AString;
|
||||
|
||||
len := Length(str);
|
||||
s := '';
|
||||
|
||||
for i:=1 to len do
|
||||
begin
|
||||
if not fCaseSensitive
|
||||
then la1 := UpCase(LA(1))
|
||||
else la1 := LA(1);
|
||||
|
||||
s := s + la1;
|
||||
|
||||
if la1 <> str[i] then
|
||||
Raise EMismatchedChar.Create( s,
|
||||
str,
|
||||
fLexerState.FileName,
|
||||
fLexerState.Line,
|
||||
fLexerState.Column)
|
||||
else
|
||||
Consume
|
||||
end;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Test Literal
|
||||
// ================================================================================================
|
||||
function TLexer.TestLiteral(AType: integer): integer;
|
||||
begin
|
||||
result := fLiterals.Value[TokenText];
|
||||
|
||||
if result < 0 then
|
||||
result := AType
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Test Literal
|
||||
// ================================================================================================
|
||||
function TLexer.TestLiteral(AText: AnsiString; AType: integer): integer;
|
||||
begin
|
||||
result := fLiterals.Value[AText];
|
||||
|
||||
if result < 0 then
|
||||
result := AType
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Tab
|
||||
//
|
||||
// Advance the current column number by an appropriate amount. If you do not override this
|
||||
// to specify how much to jump for a tab, then tabs are counted as one char. This method is
|
||||
// called from consume().
|
||||
//
|
||||
// update inputState->column as function of inputState->column and tab stops. For example,
|
||||
// if tab stops are columns 1 and 5 etc... and column is 3, then add 2 to column.
|
||||
// ================================================================================================
|
||||
procedure TLexer.Tab;
|
||||
begin
|
||||
fLexerState.Column := fLexerState.Column +1;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// UponEof
|
||||
//
|
||||
// This method is called by YourLexer::nextToken() when the lexer has hit EOF condition.
|
||||
// EOF is NOT a character. This method is not called if EOF is reached during syntactic
|
||||
// predicate evaluation or during evaluation of normal lexical rules, which presumably
|
||||
// would be an IOException. This traps the "normal" EOF condition.
|
||||
//
|
||||
// UponEOF() is called after the complete evaluation of the previous token and only if your
|
||||
// parser asks for another token beyond that last non-EOF token.
|
||||
//
|
||||
// You might want to throw token or char stream exceptions like: "Heh, premature eof" or a
|
||||
// retry stream exception ("I found the end of this file, go back to referencing file").
|
||||
// ================================================================================================
|
||||
procedure TLexer.UponEof;
|
||||
begin
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Initialize
|
||||
// ================================================================================================
|
||||
procedure TLexer.Initialize;
|
||||
begin
|
||||
end;
|
||||
// ================================================================================================
|
||||
// ReportError
|
||||
// ================================================================================================
|
||||
procedure TLexer.ReportError(e: Exception);
|
||||
begin
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// LA
|
||||
// ================================================================================================
|
||||
function TLexer.LA(i: integer): AnsiChar;
|
||||
begin
|
||||
result := fLexerState.InputBuffer.LA(i)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Commit
|
||||
// ================================================================================================
|
||||
procedure TLexer.Commit;
|
||||
begin
|
||||
fLexerState.InputBuffer.Commit
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Mark
|
||||
// ================================================================================================
|
||||
function TLexer.Mark: integer;
|
||||
begin
|
||||
result := fLexerState.InputBuffer.Mark
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Pos
|
||||
// ================================================================================================
|
||||
procedure TLexer.Rewind(Pos: integer);
|
||||
begin
|
||||
fLexerState.InputBuffer.Rewind(Pos)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// ResetText
|
||||
// ================================================================================================
|
||||
procedure TLexer.ResetText;
|
||||
begin
|
||||
TokenText := '';
|
||||
|
||||
with fLexerState do
|
||||
begin
|
||||
TokenStartLine := Line;
|
||||
TokenStartColumn := Column;
|
||||
end
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// NewLine
|
||||
// ================================================================================================
|
||||
procedure TLexer.NewLine;
|
||||
begin
|
||||
with fLexerState do
|
||||
begin
|
||||
Line := Line +1;
|
||||
Column := 1;
|
||||
end
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// MakeToken
|
||||
// ================================================================================================
|
||||
function TLexer.MakeToken(ATokenType: integer; ATokenText: AnsiString): IToken;
|
||||
begin
|
||||
if fTokenClass = nil then
|
||||
fTokenClass := TToken;
|
||||
|
||||
result := fTokenClass.Create( ATokenType, ATokenText);
|
||||
|
||||
with result, fLexerState do
|
||||
begin
|
||||
TokenLine := Line;
|
||||
TokenColumn := Column
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,221 @@
|
||||
unit dpgrtl.lexerstate;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
dpgrtl.types,
|
||||
dpgrtl.charbuffer;
|
||||
|
||||
type
|
||||
TLexerState = class( TInterfacedObject, ILexerState)
|
||||
private
|
||||
fFileName : string;
|
||||
fLine : integer;
|
||||
fColumn : integer;
|
||||
fGuessing : integer;
|
||||
|
||||
fInputBuffer : ICharBuffer;
|
||||
|
||||
fTokenStartLine : integer;
|
||||
fTokenStartColumn : integer;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// ILexerState
|
||||
// ------------------------------------------------------------
|
||||
protected
|
||||
function GetFileName : string;
|
||||
function GetLine : integer;
|
||||
function GetColumn : integer;
|
||||
function GetGuessing : integer;
|
||||
|
||||
function GetInputBuffer : ICharBuffer;
|
||||
|
||||
function GetTokenStartLine : integer;
|
||||
function GetTokenStartColumn : integer;
|
||||
|
||||
procedure SetFileName( Value: string);
|
||||
procedure SetLine( Value: integer);
|
||||
procedure SetColumn( Value: integer);
|
||||
procedure SetGuessing( Value: integer);
|
||||
|
||||
procedure SetTokenStartLine( Value: integer);
|
||||
procedure SetTokenStartColumn( Value: integer);
|
||||
|
||||
public
|
||||
constructor Create( AStream: TStream); overload;
|
||||
constructor Create( ABuffer: ICharBuffer); overload;
|
||||
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TLexerState }
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TLexerState.Create(AStream: TStream);
|
||||
begin
|
||||
inherited Create;
|
||||
fInputBuffer := TCharBuffer.Create(AStream)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TLexerState.Create(ABuffer: ICharBuffer);
|
||||
begin
|
||||
inherited Create;
|
||||
fInputBuffer := ABuffer
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TLexerState.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fFileName := '';
|
||||
fLine := 1;
|
||||
fColumn := 1;
|
||||
fGuessing := 0;
|
||||
|
||||
fTokenStartLine := 1;
|
||||
fTokenStartColumn := 1;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TLexerState.BeforeDestruction;
|
||||
begin
|
||||
fInputBuffer := nil;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
// @@@: ILexerState +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// ILexerState
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get File Name
|
||||
// ================================================================================================
|
||||
function TLexerState.GetFileName: string;
|
||||
begin
|
||||
result := fFileName
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Line number
|
||||
// ================================================================================================
|
||||
function TLexerState.GetLine: integer;
|
||||
begin
|
||||
result := fLine
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Column number
|
||||
// ================================================================================================
|
||||
function TLexerState.GetColumn: integer;
|
||||
begin
|
||||
result := fColumn
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Guessing
|
||||
// ================================================================================================
|
||||
function TLexerState.GetGuessing: integer;
|
||||
begin
|
||||
result := fGuessing
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Input Buffer
|
||||
// ================================================================================================
|
||||
function TLexerState.GetInputBuffer: ICharBuffer;
|
||||
begin
|
||||
result := fInputBuffer
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Start Line
|
||||
// ================================================================================================
|
||||
function TLexerState.GetTokenStartLine: integer;
|
||||
begin
|
||||
result := fTokenStartLine
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Start Column
|
||||
// ================================================================================================
|
||||
function TLexerState.GetTokenStartColumn: integer;
|
||||
begin
|
||||
result := fTokenStartColumn
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set File Name
|
||||
// ================================================================================================
|
||||
procedure TLexerState.SetFileName(Value: string);
|
||||
begin
|
||||
fFileName := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Line number
|
||||
// ================================================================================================
|
||||
procedure TLexerState.SetLine(Value: integer);
|
||||
begin
|
||||
fLine := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Column Number
|
||||
// ================================================================================================
|
||||
procedure TLexerState.SetColumn(Value: integer);
|
||||
begin
|
||||
fColumn := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Guessing
|
||||
// ================================================================================================
|
||||
procedure TLexerState.SetGuessing(Value: integer);
|
||||
begin
|
||||
fGuessing := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Token Start Line
|
||||
// ================================================================================================
|
||||
procedure TLexerState.SetTokenStartLine(Value: integer);
|
||||
begin
|
||||
fTokenStartLine := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Token Start Column
|
||||
// ================================================================================================
|
||||
procedure TLexerState.SetTokenStartColumn(Value: integer);
|
||||
begin
|
||||
fTokenStartColumn := Value
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,103 @@
|
||||
unit dpgrtl.llkparser;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpgrtl.parser;
|
||||
|
||||
type
|
||||
TllkParser = class( TParser)
|
||||
protected
|
||||
fK : integer;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Interface
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
procedure Consume; override;
|
||||
function LA(i:integer):byte; override;
|
||||
function LT(i:integer):IToken; override;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
constructor Create( AParserState: IParserState; K: integer); overload;
|
||||
constructor Create( ATokenBuffer: ITokenBuffer; K: integer); overload;
|
||||
constructor Create( ATokenStream: ITokenStream; K: integer); overload;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TllkParser }
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor(ParserState)
|
||||
// ================================================================================================
|
||||
constructor TllkParser.Create(AParserState: IParserState; K: integer);
|
||||
begin
|
||||
inherited Create( AParserState);
|
||||
fK := K
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(TokenBuffer)
|
||||
// ================================================================================================
|
||||
constructor TllkParser.Create(ATokenBuffer: ITokenBuffer; K: integer);
|
||||
begin
|
||||
inherited Create(ATokenBuffer);
|
||||
fK := K
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(TokenStream)
|
||||
// ================================================================================================
|
||||
constructor TllkParser.Create(ATokenStream: ITokenStream; K: integer);
|
||||
begin
|
||||
inherited Create(ATokenStream);
|
||||
fK := K
|
||||
end;
|
||||
|
||||
// @@@: Interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Consume
|
||||
// ================================================================================================
|
||||
procedure TllkParser.Consume;
|
||||
begin
|
||||
fParserState.InputBuffer.Consume
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// LA
|
||||
// ================================================================================================
|
||||
function TllkParser.LA(i: integer): byte;
|
||||
begin
|
||||
result := fParserState.InputBuffer.LA(i)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// LT
|
||||
// ================================================================================================
|
||||
function TllkParser.LT(i: integer): IToken;
|
||||
begin
|
||||
result := fParserState.InputBuffer.LT(i)
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,231 @@
|
||||
unit dpgrtl.parser;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.SysUtils,
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
TParser = class
|
||||
protected
|
||||
fParserState : IParserState;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Interface
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
procedure ConsumeUntil( ATokenType : byte); overload;
|
||||
procedure ConsumeUntil( ATokenSet : TByteSet); overload;
|
||||
|
||||
procedure Match( ATokenSet : TByteSet); overload;
|
||||
procedure Match( ATokenType : byte); overload;
|
||||
procedure MatchNot( ATokenType : byte);
|
||||
|
||||
function Mark: integer; virtual;
|
||||
procedure Rewind( Pos: integer); virtual;
|
||||
|
||||
procedure ReportError( e: Exception); overload; virtual;
|
||||
procedure ReportError( s: string); overload; virtual;
|
||||
|
||||
procedure Consume; virtual; abstract;
|
||||
function LA(i:integer): byte; virtual; abstract;
|
||||
function LT(i:integer): IToken; virtual; abstract;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
constructor Create( AState : IParserState); overload;
|
||||
constructor Create( ABuffer: ITokenBuffer); overload;
|
||||
constructor Create( AStream: ITokenStream); overload;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
property InputState : IParserState read fParserState
|
||||
write fParserState;
|
||||
end;
|
||||
|
||||
TParserClass = class of TParser;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpgrtl.exception,
|
||||
dpgrtl.parserstate,
|
||||
dpgrtl.tokenbuffer;
|
||||
|
||||
{ TParser }
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor(ParserState)
|
||||
// ================================================================================================
|
||||
constructor TParser.Create(AState: IParserState);
|
||||
begin
|
||||
inherited Create;
|
||||
fParserState := AState
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(TokenBuffer)
|
||||
// ================================================================================================
|
||||
constructor TParser.Create(ABuffer: ITokenBuffer);
|
||||
begin
|
||||
inherited Create;
|
||||
fParserState := TParserState.Create( ABuffer)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Constructor(TokenStream)
|
||||
// ================================================================================================
|
||||
constructor TParser.Create(AStream: ITokenStream);
|
||||
var
|
||||
tb: TTokenBuffer;
|
||||
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
tb := TTokenBuffer.Create(AStream);
|
||||
fParserState := TParserState.Create(tb);
|
||||
end;
|
||||
|
||||
// @@@: Interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// ConsumeUntil(TokenType)
|
||||
// ================================================================================================
|
||||
procedure TParser.ConsumeUntil(ATokenType: byte);
|
||||
var
|
||||
la1: byte;
|
||||
|
||||
begin
|
||||
la1 := LA(1);
|
||||
|
||||
while (la1 <> TT_EOF) and (la1 <> ATokenType) do
|
||||
begin
|
||||
Consume;
|
||||
la1 := LA(1)
|
||||
end
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// ConsumeUntil(TokenSet)
|
||||
// ================================================================================================
|
||||
procedure TParser.ConsumeUntil(ATokenSet: TByteSet);
|
||||
var
|
||||
la1: byte;
|
||||
|
||||
begin
|
||||
la1 := LA(1);
|
||||
|
||||
while (la1 <> TT_EOF) and not(la1 in ATokenSet) do
|
||||
begin
|
||||
Consume;
|
||||
la1 := LA(1)
|
||||
end
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Match Not
|
||||
//
|
||||
// Make sure current lookahead symbol NOT matches token type 'pTokenType'. Throw an exception
|
||||
// upon mismatch, which is catched by either the error handler or by the syntactic predicate.
|
||||
// ================================================================================================
|
||||
procedure TParser.MatchNot(ATokenType: byte);
|
||||
var
|
||||
la1: byte;
|
||||
|
||||
begin
|
||||
la1 := LA(1);
|
||||
|
||||
if la1 = ATokenType
|
||||
then Raise EMismatchedToken.Create( LT(1), ATokenType, fParserState.FileName, true)
|
||||
else Consume
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Match
|
||||
//
|
||||
// Make sure current lookahead symbol matches token type 'pTokenType'. Throw an exception upon
|
||||
// mismatch, which is catched by either the error handler or by the syntactic predicate.
|
||||
// ================================================================================================
|
||||
procedure TParser.Match(ATokenType: byte);
|
||||
var
|
||||
la1: byte;
|
||||
lt1: IToken;
|
||||
|
||||
begin
|
||||
la1 := LA(1);
|
||||
|
||||
if la1 <> ATokenType then
|
||||
begin
|
||||
lt1 := LT(1);
|
||||
Raise EMismatchedToken.Create( lt1, ATokenType, fParserState.FileName, false)
|
||||
end;
|
||||
|
||||
Consume
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Match
|
||||
//
|
||||
// Make sure current lookahead symbol matches the given set. Throw an exception upon mismatch,
|
||||
// which is catched by either the error handler or by the syntactic predicate.
|
||||
// ================================================================================================
|
||||
procedure TParser.Match(ATokenSet: TByteSet);
|
||||
var
|
||||
la1: byte;
|
||||
|
||||
begin
|
||||
la1 := LA(1);
|
||||
|
||||
if not (la1 in ATokenSet)
|
||||
then Raise EMismatchedToken.Create( LT(1), ATokenSet, fParserState.FileName, false)
|
||||
else Consume
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Mark
|
||||
// ================================================================================================
|
||||
function TParser.Mark: integer;
|
||||
begin
|
||||
result := fParserState.InputBuffer.Mark
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Rewind
|
||||
// ================================================================================================
|
||||
procedure TParser.Rewind(Pos: integer);
|
||||
begin
|
||||
fParserState.InputBuffer.Rewind(Pos)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Report Error
|
||||
// ================================================================================================
|
||||
procedure TParser.ReportError(e: Exception);
|
||||
begin
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Report Error
|
||||
// ================================================================================================
|
||||
procedure TParser.ReportError(s: string);
|
||||
begin
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,125 @@
|
||||
unit dpgrtl.parserstate;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
TParserState = class( TInterfacedObject, IParserState)
|
||||
protected
|
||||
fFileName : string;
|
||||
fGuessing : integer;
|
||||
fInputBuffer : ITokenBuffer;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// IParserState
|
||||
// ----------------------------------------------------------------------
|
||||
protected
|
||||
function GetInputBuffer : ITokenBuffer;
|
||||
function GetFileName : string;
|
||||
function GetGuessing : integer;
|
||||
|
||||
procedure SetFileName( Value: string);
|
||||
procedure SetGuessing( Value: integer);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construction/destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
constructor Create( ABuffer: ITokenBuffer);
|
||||
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TParserState }
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TParserState.Create(ABuffer: ITokenBuffer);
|
||||
begin
|
||||
inherited Create;
|
||||
fInputBuffer := ABuffer
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TParserState.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
fFileName := '';
|
||||
fGuessing := 0
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TParserState.BeforeDestruction;
|
||||
begin
|
||||
fInputBuffer := nil;
|
||||
inherited
|
||||
end;
|
||||
|
||||
// @@@: IParserState implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// IParserState implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get File Name
|
||||
// ================================================================================================
|
||||
function TParserState.GetFileName: string;
|
||||
begin
|
||||
result := fFileName
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Guessing
|
||||
// ================================================================================================
|
||||
function TParserState.GetGuessing: integer;
|
||||
begin
|
||||
result := fGuessing
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Input Buffer
|
||||
// ================================================================================================
|
||||
function TParserState.GetInputBuffer: ITokenBuffer;
|
||||
begin
|
||||
result := fInputBuffer
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set File Name
|
||||
// ================================================================================================
|
||||
procedure TParserState.SetFileName(Value: string);
|
||||
begin
|
||||
fFileName := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Guessing
|
||||
// ================================================================================================
|
||||
procedure TParserState.SetGuessing(Value: integer);
|
||||
begin
|
||||
fGuessing := Value
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,123 @@
|
||||
unit dpgrtl.stringmap;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes;
|
||||
|
||||
type
|
||||
TStringMap = class
|
||||
strict protected
|
||||
fData : TStringList;
|
||||
|
||||
private
|
||||
function GetCaseSensitive : boolean;
|
||||
function GetValue(Name:AnsiString): integer;
|
||||
|
||||
procedure SetCaseSensitive( Value: boolean);
|
||||
procedure SetValue( Name:AnsiString; Value: integer);
|
||||
|
||||
public
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
|
||||
procedure Clear;
|
||||
procedure Sort;
|
||||
|
||||
public
|
||||
property CaseSensitive : boolean read GetCaseSensitive
|
||||
write SetCaseSensitive;
|
||||
|
||||
property Value[Name:AnsiString] : integer read GetValue
|
||||
write SetValue; default;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils;
|
||||
|
||||
{ TStringMap }
|
||||
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TStringMap.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
fData := TStringList.Create
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TStringMap.BeforeDestruction;
|
||||
begin
|
||||
fData.Free;
|
||||
inherited
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get CaseSensitive
|
||||
// ================================================================================================
|
||||
function TStringMap.GetCaseSensitive: boolean;
|
||||
begin
|
||||
result := fData.CaseSensitive
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Value
|
||||
// ================================================================================================
|
||||
function TStringMap.GetValue(Name: AnsiString): integer;
|
||||
var
|
||||
idx: integer;
|
||||
|
||||
begin
|
||||
idx := fData.IndexOfName(String(Name));
|
||||
|
||||
if idx >= 0
|
||||
then result := StrToIntDef( fData.ValueFromIndex[idx], -1)
|
||||
else result := -1
|
||||
end;
|
||||
|
||||
|
||||
// ================================================================================================
|
||||
// Set CaseSensitive
|
||||
// ================================================================================================
|
||||
procedure TStringMap.SetCaseSensitive(Value: boolean);
|
||||
begin
|
||||
fData.CaseSensitive := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Value
|
||||
// ================================================================================================
|
||||
procedure TStringMap.SetValue(Name: AnsiString; Value: integer);
|
||||
var
|
||||
idx: integer;
|
||||
val: string;
|
||||
|
||||
begin
|
||||
idx := fData.IndexOfName(String(Name));
|
||||
val := IntToStr(Value);
|
||||
|
||||
if idx >= 0
|
||||
then fData.ValueFromIndex[idx] := val
|
||||
else fData.Add(String(Name)+'='+val)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clear
|
||||
// ================================================================================================
|
||||
procedure TStringMap.Clear;
|
||||
begin
|
||||
fData.Clear
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Sort
|
||||
// ================================================================================================
|
||||
procedure TStringMap.Sort;
|
||||
begin
|
||||
fData.Sort
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,139 @@
|
||||
unit dpgrtl.token;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
TToken = class( TInterfacedObject, IToken)
|
||||
strict protected
|
||||
fTokenType : byte;
|
||||
fTokenText : AnsiString;
|
||||
fTokenLine : integer;
|
||||
fTokenColumn : integer;
|
||||
|
||||
protected
|
||||
function GetTokenType : byte;
|
||||
function GetTokenText : AnsiString;
|
||||
function GetTokenLine : integer;
|
||||
function GetTokenColumn : integer;
|
||||
|
||||
procedure SetTokenType( Value: byte);
|
||||
procedure SetTokenText( Value: AnsiString);
|
||||
procedure SetTokenLine( Value: integer);
|
||||
procedure SetTokenColumn( Value: integer);
|
||||
|
||||
public
|
||||
function Clone: IToken;
|
||||
|
||||
public
|
||||
constructor Create( ATokenType : byte=TT_INVALID;
|
||||
ATokenText : AnsiString='';
|
||||
ATokenLine : integer=0;
|
||||
ATokenColumn: integer=0);
|
||||
public
|
||||
end;
|
||||
|
||||
TTokenClass = class of TToken;
|
||||
|
||||
var
|
||||
badToken : IToken;
|
||||
nullToken: IToken;
|
||||
|
||||
implementation
|
||||
|
||||
// ================================================================================================
|
||||
// constructor
|
||||
// ================================================================================================
|
||||
constructor TToken.Create( ATokenType : byte;
|
||||
ATokenText : AnsiString;
|
||||
ATokenLine : integer;
|
||||
ATokenColumn: integer);
|
||||
begin
|
||||
fTokenType := ATokenType;
|
||||
fTokenText := ATokenText;
|
||||
fTokenLine := ATokenLine;
|
||||
fTokenColumn:= ATokenColumn
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Text
|
||||
// ================================================================================================
|
||||
function TToken.GetTokenText: AnsiString;
|
||||
begin
|
||||
result := fTokenText
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Type
|
||||
// ================================================================================================
|
||||
function TToken.GetTokenType: byte;
|
||||
begin
|
||||
result := fTokenType
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Line
|
||||
// ================================================================================================
|
||||
function TToken.GetTokenLine: integer;
|
||||
begin
|
||||
result := fTokenLine
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Column
|
||||
// ================================================================================================
|
||||
function TToken.GetTokenColumn: integer;
|
||||
begin
|
||||
result := fTokenColumn
|
||||
end;
|
||||
|
||||
|
||||
// ================================================================================================
|
||||
// Set Token Text
|
||||
// ================================================================================================
|
||||
procedure TToken.SetTokenText( Value: AnsiString);
|
||||
begin
|
||||
fTokenText := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Token Type
|
||||
// ================================================================================================
|
||||
procedure TToken.SetTokenType( Value: byte);
|
||||
begin
|
||||
fTokenType := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Token Line
|
||||
// ================================================================================================
|
||||
procedure TToken.SetTokenLine( Value: integer);
|
||||
begin
|
||||
fTokenLine := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Token Line
|
||||
// ================================================================================================
|
||||
procedure TToken.SetTokenColumn( Value: integer);
|
||||
begin
|
||||
fTokenColumn := Value
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Clone
|
||||
// ================================================================================================
|
||||
function TToken.Clone: IToken;
|
||||
begin
|
||||
result := TToken.Create( fTokenType, fTokenText, fTokenLine, fTokenColumn);
|
||||
end;
|
||||
|
||||
initialization
|
||||
badToken := TToken.Create( TT_INVALID);
|
||||
nullToken := TToken.Create( TT_INVALID);
|
||||
|
||||
finalization
|
||||
badToken := nil;
|
||||
nullToken := nil;
|
||||
end.
|
||||
@@ -0,0 +1,162 @@
|
||||
unit dpgrtl.tokenbuffer;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpgrtl.inputbuffer,
|
||||
dpgrtl.tokenqueue;
|
||||
|
||||
type
|
||||
TTokenBuffer = class( TInputBuffer, IInputBuffer, ITokenBuffer)
|
||||
protected
|
||||
fStream : ITokenStream;
|
||||
fQueue : TTokenQueue;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Internals
|
||||
// ------------------------------------------------------------
|
||||
protected
|
||||
function GetNext: IToken; inline;
|
||||
procedure Fill( Amount: integer);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// TInputBuffer override
|
||||
// ------------------------------------------------------------
|
||||
protected
|
||||
procedure Remove( Num: integer); override;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// ITokenBuffer
|
||||
// ------------------------------------------------------------
|
||||
protected
|
||||
function LA(i: integer): integer;
|
||||
function LT(i: integer): IToken;
|
||||
|
||||
public
|
||||
constructor Create( AStream: ITokenStream);
|
||||
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TTokenBuffer }
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Constructor
|
||||
// ================================================================================================
|
||||
constructor TTokenBuffer.Create(AStream: ITokenStream);
|
||||
begin
|
||||
inherited Create;
|
||||
fStream := AStream;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TTokenBuffer.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
fQueue := TTokenQueue.Create
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TTokenBuffer.BeforeDestruction;
|
||||
begin
|
||||
fStream := nil;
|
||||
fQueue.Free;
|
||||
inherited
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// @@@: ITokenBuffer implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// ITokenBuffer implementation
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// LA
|
||||
//
|
||||
// Ensure that the 'fQueue' object hold sufficient tokens, and gets the 'i'th LookAhead token
|
||||
// type from the 'fQueue'.
|
||||
// ================================================================================================
|
||||
function TTokenBuffer.LA(i: integer): integer;
|
||||
begin
|
||||
Fill(i);
|
||||
result := fQueue.Items[ fMarkerOffset +i -1].TokenType
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// LT
|
||||
// ================================================================================================
|
||||
function TTokenBuffer.LT(i: integer): IToken;
|
||||
begin
|
||||
Fill(i);
|
||||
result := fQueue.Items[ fMarkerOffset +i -1]
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// @@@: Internals +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Internals
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Next
|
||||
// ================================================================================================
|
||||
function TTokenBuffer.GetNext: IToken;
|
||||
begin
|
||||
result := fStream.NextToken
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Fill
|
||||
// ================================================================================================
|
||||
procedure TTokenBuffer.Fill(Amount: integer);
|
||||
begin
|
||||
SyncConsume;
|
||||
|
||||
while fQueue.Count < (Amount +fMarkerOffset) do
|
||||
fQueue.Add( GetNext);
|
||||
end;
|
||||
|
||||
// @@@: TInputBuffer overrides ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// TInputBuffer overrides
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Remove
|
||||
// ================================================================================================
|
||||
procedure TTokenBuffer.Remove(Num: integer);
|
||||
begin
|
||||
fQueue.Remove(Num)
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,157 @@
|
||||
unit dpgrtl.tokenqueue;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
TTokenQueue = class( TInterfacedObject)
|
||||
private
|
||||
fItems : TInterfaceList;
|
||||
|
||||
private
|
||||
function GetCount : integer;
|
||||
function GetItem(i:integer): IToken;
|
||||
procedure SetItem(i:integer;value:IToken);
|
||||
|
||||
public
|
||||
procedure Clear;
|
||||
procedure Add( Item: IToken);
|
||||
procedure Remove( Num: integer=1);
|
||||
|
||||
public
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
|
||||
public
|
||||
property Count : integer read GetCount;
|
||||
property Items[i:integer] : IToken read GetItem write SetItem;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
System.SysUtils;
|
||||
|
||||
{ TTokenQueue }
|
||||
|
||||
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction/destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TTokenQueue.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fItems := TInterfaceList.Create;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TTokenQueue.BeforeDestruction;
|
||||
begin
|
||||
FreeAndNil(fItems);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// @@@: Interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Clear
|
||||
// ================================================================================================
|
||||
procedure TTokenQueue.Clear;
|
||||
begin
|
||||
fItems.Clear;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Add
|
||||
// ================================================================================================
|
||||
procedure TTokenQueue.Add(Item: IToken);
|
||||
begin
|
||||
if Assigned(Item) then
|
||||
fItems.Add(Item)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Remove
|
||||
// ================================================================================================
|
||||
procedure TTokenQueue.Remove(Num: integer);
|
||||
var
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
if Num > 0 then
|
||||
begin
|
||||
if Num >= fItems.Count then
|
||||
fItems.Clear
|
||||
|
||||
else
|
||||
for i:=0 to Num -1 do
|
||||
fItems.Delete(0)
|
||||
end
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// @@@: Property Handlers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Property Handlers
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Get Count
|
||||
// ================================================================================================
|
||||
function TTokenQueue.GetCount: integer;
|
||||
begin
|
||||
result := fItems.Count
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Item
|
||||
// ================================================================================================
|
||||
function TTokenQueue.GetItem(i: integer): IToken;
|
||||
begin
|
||||
// -------------------------------------------------------------------------
|
||||
// Check for valid index value.
|
||||
// -------------------------------------------------------------------------
|
||||
if i > fItems.Count then raise ERangeError.CreateFmt( 'Index "%d" is too big', [i]);
|
||||
if i < 0 then raise ERangeError.CreateFmt( 'Index is less than 0', []);
|
||||
|
||||
result := fItems[i] as IToken
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Item
|
||||
// ================================================================================================
|
||||
procedure TTokenQueue.SetItem(i: integer; value: IToken);
|
||||
begin
|
||||
if i > fItems.Count then raise ERangeError.CreateFmt( 'Index "%d" is too big', [i]);
|
||||
if i < 0 then raise ERangeError.CreateFmt( 'Index is less than 0', []);
|
||||
|
||||
fItems.Items[i] := value
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,147 @@
|
||||
unit dpgrtl.treeparser;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types,
|
||||
dpgrtl.astBase,
|
||||
dpgrtl.astFactory,
|
||||
dpgrtl.treeparserstate;
|
||||
|
||||
type
|
||||
TTreeParser = class
|
||||
|
||||
// The AST Null object; the parsing cursor is set to this when
|
||||
// it is found to be null. This way, we can test the token type
|
||||
// of a node without having to have tests for null everywhere.
|
||||
|
||||
// public static ASTNULLType ASTNULL = new ASTNULLType
|
||||
|
||||
|
||||
protected
|
||||
fASTNULL : TAST;
|
||||
|
||||
|
||||
|
||||
// Where did this rule leave off parsing;
|
||||
// avoids a return parameter
|
||||
fRetTree : TAST;
|
||||
|
||||
fInputState : TTreeParserState;
|
||||
|
||||
// table of token type to token names
|
||||
fTokenNames : TTokenNameMap;
|
||||
|
||||
// AST return value for a rule is squirreled away here
|
||||
fRetAST : TAST;
|
||||
|
||||
// AST support code; parser and tree parser delegate to this object
|
||||
fASTFactory : TASTFactory;
|
||||
|
||||
// Used to keep track of indent depth for trace In/Out
|
||||
fTraceDepth : integer;
|
||||
|
||||
protected
|
||||
procedure match( ast : TAST;
|
||||
typ : integer); overload;
|
||||
|
||||
procedure match( ast : TAST;
|
||||
bits : TByteSet); overload;
|
||||
|
||||
procedure matchNot(ast : TAST;
|
||||
typ : integer);
|
||||
|
||||
|
||||
|
||||
private
|
||||
function GetTokenName( i: integer): AnsiString;
|
||||
|
||||
public
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
|
||||
public
|
||||
property AST : TAST read fRetAST;
|
||||
|
||||
property ASTFactory : TASTFactory read fASTFactory;
|
||||
|
||||
property TokenName[i: integer] : AnsiString read GetTokenName;
|
||||
property TokenNames : TTokenNameMap read fTokenNames;
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
dpgrtl.exception,
|
||||
System.SysUtils;
|
||||
|
||||
{ TTreeParser }
|
||||
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TTreeParser.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fTraceDepth := 0;
|
||||
fInputState := TTreeParserState .Create;
|
||||
fTokenNames := TTokenNameMap .Create;
|
||||
fASTFactory := TASTFactory .Create(nil);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TTreeParser.BeforeDestruction;
|
||||
begin
|
||||
FreeAndNil( fTokenNames);
|
||||
FreeAndNil( fInputState);
|
||||
FreeAndNil( fASTFactory);
|
||||
inherited
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Token Name
|
||||
// ================================================================================================
|
||||
function TTreeParser.GetTokenName(i: integer): AnsiString;
|
||||
begin
|
||||
result := '';
|
||||
|
||||
if Assigned(fTokenNames) then
|
||||
fTokenNames.TryGetValue(i, result)
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// match( AST, type)
|
||||
// ================================================================================================
|
||||
procedure TTreeParser.match(ast: TAST; typ: integer);
|
||||
begin
|
||||
// TODO: Exception creation check!
|
||||
|
||||
if (ast = nil) or (ast = fASTNULL) or (ast.AstType <> typ) then
|
||||
raise Exception.Create('TREE: Mismatched token.');
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// match ( AST, byteset)
|
||||
//
|
||||
// Make sure current lookahead symbol matches the given set.
|
||||
// Throw an exception upon mismatch, which is catch by either the error handler or by the
|
||||
// syntactic predicate.
|
||||
// ================================================================================================
|
||||
procedure TTreeParser.match(ast: TAST; bits: TByteSet);
|
||||
begin
|
||||
if (ast = nil) or (ast = fASTNULL) or not (ast.AstType in bits) then
|
||||
raise Exception.Create('TREE: Mismatched token.');
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// match not
|
||||
// ================================================================================================
|
||||
procedure TTreeParser.matchNot(ast: TAST; typ: integer);
|
||||
begin
|
||||
if (ast = nil) or (ast = fASTNULL) or (ast.AstType = typ) then
|
||||
raise Exception.Create('TREE: Mismatched token.');
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,49 @@
|
||||
unit dpgrtl.treeparserstate;
|
||||
|
||||
interface
|
||||
uses
|
||||
dpgrtl.types;
|
||||
|
||||
type
|
||||
TTreeParserState = class( TInterfacedObject, ITreeParserState)
|
||||
protected
|
||||
fGuessing : integer;
|
||||
|
||||
protected
|
||||
function GetGuessing: integer;
|
||||
procedure SetGuessing( Value: integer);
|
||||
|
||||
public
|
||||
procedure AfterConstruction; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TParserState }
|
||||
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TTreeParserState.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
fGuessing := 0;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Get Guessing
|
||||
// ================================================================================================
|
||||
function TTreeParserState.GetGuessing: integer;
|
||||
begin
|
||||
result := fGuessing
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Set Guessing
|
||||
// ================================================================================================
|
||||
procedure TTreeParserState.SetGuessing(Value: integer);
|
||||
begin
|
||||
fGuessing := Value
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,182 @@
|
||||
unit dpgrtl.types;
|
||||
|
||||
interface
|
||||
uses
|
||||
Generics.Collections,
|
||||
System.SysUtils;
|
||||
|
||||
const
|
||||
// -------------------------------------------------------------------------
|
||||
// autogen values
|
||||
// -------------------------------------------------------------------------
|
||||
AUTOGEN_INVALID = 0;
|
||||
AUTOGEN_NONE = 1;
|
||||
AUTOGEN_CARET = 2;
|
||||
AUTOGEN_BANG = 3;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// predefined token types
|
||||
// -------------------------------------------------------------------------
|
||||
TT_SKIP = $FF;
|
||||
TT_INVALID = 0;
|
||||
TT_EOF = 1;
|
||||
TT_NTLA = 2; // null tree lookahead
|
||||
TT_USER = 4;
|
||||
|
||||
EOF_CHAR = #0;
|
||||
|
||||
type
|
||||
TByteSet = set of 0..255;
|
||||
TCharSet = set of AnsiChar;
|
||||
TCharMatrix = array of array of AnsiChar;
|
||||
|
||||
TTokenNameMap = TDictionary<integer,AnsiString>;
|
||||
|
||||
// ===================================================================================
|
||||
// IToken interface
|
||||
// ===================================================================================
|
||||
IToken = interface
|
||||
['{BFB516D6-7175-40C8-9AA0-592CA11AD391}']
|
||||
|
||||
function GetTokenType : byte;
|
||||
function GetTokenText : AnsiString;
|
||||
function GetTokenLine : integer;
|
||||
function GetTokenColumn : integer;
|
||||
|
||||
procedure SetTokenType( Value: byte);
|
||||
procedure SetTokenText( Value: AnsiString);
|
||||
procedure SetTokenLine( Value: integer);
|
||||
procedure SetTokenColumn( Value: integer);
|
||||
|
||||
function Clone: IToken;
|
||||
|
||||
property TokenType : byte read GetTokenType write SetTokenType;
|
||||
property TokenText : AnsiString read GetTokenText write SetTokenText;
|
||||
property TokenLine : integer read GetTokenLine write SetTokenLine;
|
||||
property TokenColumn : integer read GetTokenColumn write SetTokenColumn;
|
||||
end;
|
||||
|
||||
// ===================================================================================
|
||||
// ITokenStream interface
|
||||
// ===================================================================================
|
||||
ITokenStream = interface
|
||||
['{48293450-4B0C-455B-BC3C-313363C503D2}']
|
||||
|
||||
function NextToken: IToken;
|
||||
end;
|
||||
|
||||
// ===================================================================================
|
||||
// IInputBuffer interface
|
||||
// ===================================================================================
|
||||
IInputBuffer = interface
|
||||
['{936C26A0-E25F-4B4E-9FD3-5E8E7FC23B17}']
|
||||
|
||||
function GetMarked: boolean;
|
||||
|
||||
procedure Consume;
|
||||
procedure Commit;
|
||||
|
||||
function Mark: integer;
|
||||
procedure Rewind( Value: integer);
|
||||
|
||||
property Marked: boolean read GetMarked;
|
||||
end;
|
||||
|
||||
// ===================================================================================
|
||||
// ICharBuffer interface
|
||||
// ===================================================================================
|
||||
ICharBuffer = interface( IInputBuffer)
|
||||
['{AA5CD21F-7982-4FF4-BB52-7A02B65C35A8}']
|
||||
|
||||
function LA(i: integer): AnsiChar;
|
||||
end;
|
||||
|
||||
// ===================================================================================
|
||||
// ITokenBuffer interface
|
||||
// ===================================================================================
|
||||
ITokenBuffer = interface( IInputBuffer)
|
||||
['{1FD2EB56-5385-49B0-815D-8B7F96E33F1A}']
|
||||
|
||||
function LA(i: integer): integer;
|
||||
function LT(i: integer): IToken;
|
||||
end;
|
||||
|
||||
// ===================================================================================
|
||||
// ILexerState
|
||||
// ===================================================================================
|
||||
ILexerState = interface
|
||||
['{D6E15235-CADC-48BA-9390-376284515FAA}']
|
||||
|
||||
function GetFileName : string;
|
||||
function GetLine : integer;
|
||||
function GetColumn : integer;
|
||||
function GetGuessing : integer;
|
||||
|
||||
function GetInputBuffer : ICharBuffer;
|
||||
|
||||
function GetTokenStartLine : integer;
|
||||
function GetTokenStartColumn : integer;
|
||||
|
||||
procedure SetFileName( Value: string);
|
||||
procedure SetLine( Value: integer);
|
||||
procedure SetColumn( Value: integer);
|
||||
procedure SetGuessing( Value: integer);
|
||||
|
||||
procedure SetTokenStartLine( Value: integer);
|
||||
procedure SetTokenStartColumn( Value: integer);
|
||||
|
||||
property FileName : string read GetFileName
|
||||
write SetFileName;
|
||||
|
||||
property Line : integer read GetLine
|
||||
write SetLine;
|
||||
|
||||
property Column : integer read GetColumn
|
||||
write SetColumn;
|
||||
|
||||
property Guessing : integer read GetGuessing
|
||||
write SetGuessing;
|
||||
|
||||
property TokenStartLine : integer read GetTokenStartLine
|
||||
write SetTokenStartLine;
|
||||
|
||||
property TokenStartColumn : integer read GetTokenStartColumn
|
||||
write SetTokenStartColumn;
|
||||
|
||||
property InputBuffer : ICharBuffer read GetInputBuffer;
|
||||
end;
|
||||
|
||||
// ===================================================================================
|
||||
// IParserState
|
||||
// ===================================================================================
|
||||
IParserState = interface
|
||||
['{763A4DAD-91F5-4225-A68D-8FE4B1A29164}']
|
||||
|
||||
function GetFileName : string;
|
||||
function GetGuessing : integer;
|
||||
function GetInputBuffer : ITokenBuffer;
|
||||
|
||||
procedure SetFileName( Value: string);
|
||||
procedure SetGuessing( Value: integer);
|
||||
|
||||
property FileName : string read GetFileName write SetFileName;
|
||||
property Guessing : integer read GetGuessing write SetGuessing;
|
||||
property InputBuffer : ITokenBuffer read GetInputBuffer;
|
||||
end;
|
||||
|
||||
// ===================================================================================
|
||||
// ITreeParserState
|
||||
// ===================================================================================
|
||||
ITreeParserState = interface
|
||||
['{439DCDAA-B1AB-482A-BAAE-843917F60E42}']
|
||||
|
||||
function GetGuessing: integer;
|
||||
procedure SetGuessing( Value: integer);
|
||||
|
||||
property Guessing: integer read GetGuessing write SetGuessing;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user