You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2137 lines
66 KiB
2137 lines
66 KiB
unit Antlr.Runtime.Tree.Tests;
|
|
{
|
|
|
|
Delphi DUnit Test Case
|
|
----------------------
|
|
This unit contains a skeleton test case class generated by the Test Case Wizard.
|
|
Modify the generated code to correctly setup and call the methods from the unit
|
|
being tested.
|
|
|
|
}
|
|
|
|
interface
|
|
|
|
uses
|
|
TestFramework,
|
|
Antlr.Runtime.Collections,
|
|
Antlr.Runtime.Tree,
|
|
Classes,
|
|
SysUtils,
|
|
Antlr.Runtime,
|
|
Antlr.Runtime.Tools;
|
|
|
|
type
|
|
// Test methods for class ICommonTree
|
|
TestICommonTree = class(TTestCase)
|
|
public
|
|
procedure SetUp; override;
|
|
procedure TearDown; override;
|
|
published
|
|
procedure TestSingleNode;
|
|
procedure Test4Nodes;
|
|
procedure TestList;
|
|
procedure TestList2;
|
|
procedure TestAddListToExistChildren;
|
|
procedure TestDupTree;
|
|
procedure TestBecomeRoot;
|
|
procedure TestBecomeRoot2;
|
|
procedure TestBecomeRoot3;
|
|
procedure TestBecomeRoot5;
|
|
procedure TestBecomeRoot6;
|
|
procedure TestReplaceWithNoChildren;
|
|
procedure TestReplaceWithOneChildren;
|
|
procedure TestReplaceInMiddle;
|
|
procedure TestReplaceAtLeft;
|
|
procedure TestReplaceAtRight;
|
|
procedure TestReplaceOneWithTwoAtLeft;
|
|
procedure TestReplaceOneWithTwoAtRight;
|
|
procedure TestReplaceOneWithTwoInMiddle;
|
|
procedure TestReplaceTwoWithOneAtLeft;
|
|
procedure TestReplaceTwoWithOneAtRight;
|
|
procedure TestReplaceAllWithOne;
|
|
procedure TestReplaceAllWithTwo;
|
|
end;
|
|
|
|
// Test methods for class ICommonTreeNodeStream
|
|
TestICommonTreeNodeStream = class(TTestCase)
|
|
private
|
|
function CreateCommonTreeNodeStream(const T: IANTLRInterface): ITreeNodeStream;
|
|
function GetStringOfEntireStreamContentsWithNodeTypesOnly(
|
|
const Nodes: ITreeNodeStream): String;
|
|
function CreateUnBufferedTreeNodeStream(const T: IANTLRInterface): ITreeNodeStream;
|
|
public
|
|
procedure SetUp; override;
|
|
procedure TearDown; override;
|
|
published
|
|
procedure TestSingleNode;
|
|
procedure Test4Nodes;
|
|
procedure TestList;
|
|
procedure TestFlatList;
|
|
procedure TestListWithOneNode;
|
|
procedure TestAoverB;
|
|
procedure TestLT;
|
|
procedure TestMarkRewindEntire;
|
|
procedure TestMarkRewindInMiddle;
|
|
procedure TestMarkRewindNested;
|
|
procedure TestSeek;
|
|
procedure TestSeekFromStart;
|
|
procedure TestPushPop;
|
|
procedure TestNestedPushPop;
|
|
procedure TestPushPopFromEOF;
|
|
procedure TestStackStretch;
|
|
procedure TestBufferOverflow;
|
|
procedure TestBufferWrap;
|
|
end;
|
|
|
|
// Test methods for class IRewriteRuleXxxxStream
|
|
TestIRewriteRuleXxxxStream = class(TTestCase)
|
|
strict private
|
|
function CreateTreeAdaptor: ITreeAdaptor;
|
|
function CreateTree(const Token: IToken): ITree;
|
|
function CreateToken(const TokenType: Integer; const Text: String): IToken;
|
|
function CreateTokenList(const Count: Integer): IList<IToken>;
|
|
public
|
|
procedure SetUp; override;
|
|
procedure TearDown; override;
|
|
published
|
|
procedure TestRewriteRuleTokenStreamConstructors;
|
|
procedure TestRewriteRuleSubtreeStreamConstructors;
|
|
procedure TestRewriteRuleNodeStreamConstructors;
|
|
|
|
procedure TestRRTokenStreamBehaviourWhileEmpty1;
|
|
procedure TestRRSubtreeStreamBehaviourWhileEmpty1;
|
|
procedure TestRRNodeStreamBehaviourWhileEmpty1;
|
|
|
|
procedure TestRRTokenStreamBehaviourWhileEmpty2;
|
|
procedure TestRRSubtreeStreamBehaviourWhileEmpty2;
|
|
procedure TestRRNodeStreamBehaviourWhileEmpty2;
|
|
|
|
procedure TestRRTokenStreamBehaviourWhileEmpty3;
|
|
|
|
procedure TestRRTokenStreamBehaviourWithElements;
|
|
procedure TestRRSubtreeStreamBehaviourWithElements;
|
|
procedure TestRRNodeStreamBehaviourWithElements;
|
|
end;
|
|
|
|
// Test methods for class ITreeWizard
|
|
TestITreeWizard = class(TTestCase)
|
|
strict private
|
|
FTokens: TStringArray;
|
|
strict private
|
|
type
|
|
TRecordAllElementsVisitor = class sealed(TTreeWizard.TVisitor)
|
|
strict private
|
|
FList: IList<IANTLRInterface>;
|
|
strict protected
|
|
procedure Visit(const T: IANTLRInterface); override;
|
|
public
|
|
constructor Create(const AList: IList<IANTLRInterface>);
|
|
end;
|
|
|
|
TTest1ContextVisitor = class sealed(TANTLRObject, IContextVisitor)
|
|
strict private
|
|
FAdaptor: ITreeAdaptor;
|
|
FList: IList<IANTLRInterface>;
|
|
protected
|
|
{ IContextVisitor }
|
|
procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer;
|
|
const Labels: IDictionary<String, IANTLRInterface>);
|
|
public
|
|
constructor Create(const AAdaptor: ITreeAdaptor;
|
|
const AList: IList<IANTLRInterface>);
|
|
end;
|
|
|
|
TTest2ContextVisitor = class sealed(TANTLRObject, IContextVisitor)
|
|
strict private
|
|
FAdaptor: ITreeAdaptor;
|
|
FList: IList<IANTLRInterface>;
|
|
protected
|
|
{ IContextVisitor }
|
|
procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer;
|
|
const Labels: IDictionary<String, IANTLRInterface>);
|
|
public
|
|
constructor Create(const AAdaptor: ITreeAdaptor;
|
|
const AList: IList<IANTLRInterface>);
|
|
end;
|
|
public
|
|
constructor Create(MethodName: String); override;
|
|
procedure SetUp; override;
|
|
procedure TearDown; override;
|
|
published
|
|
procedure TestSingleNode;
|
|
procedure TestSingleNodeWithArg;
|
|
procedure TestSingleNodeTree;
|
|
procedure TestSingleLevelTree;
|
|
procedure TestListTree;
|
|
procedure TestInvalidListTree;
|
|
procedure TestDoubleLevelTree;
|
|
procedure TestSingleNodeIndex;
|
|
procedure TestNoRepeatsIndex;
|
|
procedure TestRepeatsIndex;
|
|
procedure TestNoRepeatsVisit;
|
|
procedure TestNoRepeatsVisit2;
|
|
procedure TestRepeatsVisit;
|
|
procedure TestRepeatsVisit2;
|
|
procedure TestRepeatsVisitWithContext;
|
|
procedure TestRepeatsVisitWithNullParentAndContext;
|
|
procedure TestVisitPattern;
|
|
procedure TestVisitPatternMultiple;
|
|
procedure TestVisitPatternMultipleWithLabels;
|
|
procedure TestParse;
|
|
procedure TestParseSingleNode;
|
|
procedure TestParseFlatTree;
|
|
procedure TestWildcard;
|
|
procedure TestParseWithText;
|
|
procedure TestParseWithTextFails;
|
|
procedure TestParseLabels;
|
|
procedure TestParseWithWildcardLabels;
|
|
procedure TestParseLabelsAndTestText;
|
|
procedure TestParseLabelsInNestedTree;
|
|
procedure TestEquals;
|
|
procedure TestEqualsWithText;
|
|
procedure TestEqualsWithMismatchedText;
|
|
procedure TestFindPattern;
|
|
end;
|
|
|
|
implementation
|
|
|
|
procedure TestICommonTree.SetUp;
|
|
begin
|
|
end;
|
|
|
|
procedure TestICommonTree.TearDown;
|
|
begin
|
|
end;
|
|
|
|
procedure TestICommonTree.Test4Nodes;
|
|
var
|
|
R0: ICommonTree;
|
|
begin
|
|
// ^(101 ^(102 103) 104)
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
R0.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
CheckNull(R0.Parent);
|
|
CheckEquals(R0.ChildIndex,-1);
|
|
end;
|
|
|
|
procedure TestICommonTree.TestAddListToExistChildren;
|
|
var
|
|
Root, R0, C0, C1, C2: ICommonTree;
|
|
begin
|
|
// Add child ^(nil 101 102 103) to root ^(5 6)
|
|
// should add 101 102 103 to end of 5's child list
|
|
Root := TCommonTree.Create(TCommonToken.Create(5));
|
|
Root.AddChild(TCommonTree.Create(TCommonToken.Create(6)));
|
|
|
|
// child tree
|
|
R0 := TCommonTree.Create(IToken(nil));
|
|
C0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
C1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
C2 := TCommonTree.Create(TCommonToken.Create(103));
|
|
R0.AddChild(C0);
|
|
R0.AddChild(C1);
|
|
R0.AddChild(C2);
|
|
|
|
Root.AddChild(R0);
|
|
|
|
CheckNull(Root.Parent);
|
|
CheckEquals(Root.ChildIndex, -1);
|
|
|
|
// check children of root all point at root
|
|
Check(C0.Parent = Root);
|
|
Check(C0.ChildIndex = 1);
|
|
Check(C1.Parent = Root);
|
|
Check(C1.ChildIndex = 2);
|
|
Check(C2.Parent = Root);
|
|
Check(C2.ChildIndex = 3);
|
|
end;
|
|
|
|
procedure TestICommonTree.TestBecomeRoot;
|
|
var
|
|
OldRoot, NewRoot: ICommonTree;
|
|
Adaptor: ITreeAdaptor;
|
|
begin
|
|
// 5 becomes new root of ^(nil 101 102 103)
|
|
NewRoot := TCommonTree.Create(TCommonToken.Create(5));
|
|
OldRoot := TCommonTree.Create(IToken(nil));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(101)));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Adaptor.BecomeRoot(NewRoot, OldRoot);
|
|
NewRoot.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestBecomeRoot2;
|
|
var
|
|
OldRoot, NewRoot: ICommonTree;
|
|
Adaptor: ITreeAdaptor;
|
|
begin
|
|
// 5 becomes new root of ^(101 102 103)
|
|
NewRoot := TCommonTree.Create(TCommonToken.Create(5));
|
|
OldRoot := TCommonTree.Create(TCommonToken.Create(101));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Adaptor.BecomeRoot(NewRoot, OldRoot);
|
|
NewRoot.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestBecomeRoot3;
|
|
var
|
|
OldRoot, NewRoot: ICommonTree;
|
|
Adaptor: ITreeAdaptor;
|
|
begin
|
|
// ^(nil 5) becomes new root of ^(nil 101 102 103)
|
|
NewRoot := TCommonTree.Create(IToken(nil));
|
|
NewRoot.AddChild(TCommonTree.Create(TCommonToken.Create(5)));
|
|
OldRoot := TCommonTree.Create(IToken(nil));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(101)));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Adaptor.BecomeRoot(NewRoot, OldRoot);
|
|
NewRoot.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestBecomeRoot5;
|
|
var
|
|
OldRoot, NewRoot: ICommonTree;
|
|
Adaptor: ITreeAdaptor;
|
|
begin
|
|
// ^(nil 5) becomes new root of ^(101 102 103)
|
|
NewRoot := TCommonTree.Create(IToken(nil));
|
|
NewRoot.AddChild(TCommonTree.Create(TCommonToken.Create(5)));
|
|
OldRoot := TCommonTree.Create(TCommonToken.Create(101));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
OldRoot.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Adaptor.BecomeRoot(NewRoot, OldRoot);
|
|
NewRoot.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestBecomeRoot6;
|
|
var
|
|
Root0, Root1: ICommonTree;
|
|
Adaptor: ITreeAdaptor;
|
|
begin
|
|
// emulates construction of ^(5 6)
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Root0 := Adaptor.GetNilNode as ICommonTree;
|
|
Root1 := Adaptor.GetNilNode as ICommonTree;
|
|
Root1 := Adaptor.BecomeRoot(TCommonTree.Create(TCommonToken.Create(5)), Root1) as ICommonTree;
|
|
Adaptor.AddChild(Root1, TCommonTree.Create(TCommonToken.Create(6)));
|
|
Adaptor.AddChild(Root0, Root1);
|
|
Root0.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestDupTree;
|
|
var
|
|
R0, R1, Dup: ICommonTree;
|
|
R2: ITree;
|
|
Adaptor: ICommonTreeAdaptor;
|
|
begin
|
|
// ^(101 ^(102 103 ^(106 107) ) 104 105)
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
R0.AddChild(R1);
|
|
R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R2 := TCommonTree.Create(TCommonToken.Create(106));
|
|
R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
|
|
R1.AddChild(R2);
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
|
|
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Dup := Adaptor.DupTree(R0) as ICommonTree;
|
|
|
|
CheckNull(Dup.Parent);
|
|
CheckEquals(Dup.ChildIndex, -1);
|
|
Dup.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestList;
|
|
var
|
|
R0, C0, C1, C2: ICommonTree;
|
|
begin
|
|
// ^(nil 101 102 103)
|
|
R0 := TCommonTree.Create(IToken(nil));
|
|
C0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
C1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
C2 := TCommonTree.Create(TCommonToken.Create(103));
|
|
R0.AddChild(C0);
|
|
R0.AddChild(C1);
|
|
R0.AddChild(C2);
|
|
|
|
CheckNull(R0.Parent);
|
|
CheckEquals(R0.ChildIndex, -1);
|
|
Check(C0.Parent = R0);
|
|
CheckEquals(C0.ChildIndex, 0);
|
|
Check(C1.Parent = R0);
|
|
CheckEquals(C1.ChildIndex, 1);
|
|
Check(C2.Parent = R0);
|
|
CheckEquals(C2.ChildIndex, 2);
|
|
end;
|
|
|
|
procedure TestICommonTree.TestList2;
|
|
var
|
|
Root, R0, C0, C1, C2: ICommonTree;
|
|
begin
|
|
// Add child ^(nil 101 102 103) to root 5
|
|
// should pull 101 102 103 directly to become 5's child list
|
|
Root := TCommonTree.Create(TClassicToken.Create(5));
|
|
|
|
// child tree
|
|
R0 := TCommonTree.Create(IToken(nil));
|
|
C0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
C1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
C2 := TCommonTree.Create(TCommonToken.Create(103));
|
|
R0.AddChild(C0);
|
|
R0.AddChild(C1);
|
|
R0.AddChild(C2);
|
|
|
|
Root.AddChild(R0);
|
|
|
|
CheckNull(Root.Parent);
|
|
CheckEquals(Root.ChildIndex, -1);
|
|
|
|
// check children of root all point at root
|
|
Check(C0.Parent = Root);
|
|
Check(C0.ChildIndex = 0);
|
|
Check(C1.Parent = Root);
|
|
Check(C1.ChildIndex = 1);
|
|
Check(C2.Parent = Root);
|
|
Check(C2.ChildIndex = 2);
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceAllWithOne;
|
|
var
|
|
T, NewChild: ICommonTree;
|
|
begin
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
|
|
NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
|
|
T.ReplaceChildren(0, 2, NewChild);
|
|
CheckEquals(T.ToStringTree, '(a x)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceAllWithTwo;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
T, NewChildren: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
|
|
NewChildren := Adaptor.GetNilNode as ICommonTree;
|
|
NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x')));
|
|
NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y')));
|
|
T.ReplaceChildren(0, 2, NewChildren);
|
|
CheckEquals(T.ToStringTree, '(a x y)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceAtLeft;
|
|
var
|
|
T, NewChild: ICommonTree;
|
|
begin
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b'))); // index 0
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
|
|
NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
|
|
T.ReplaceChildren(0, 0, NewChild);
|
|
CheckEquals(T.ToStringTree, '(a x c d)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceAtRight;
|
|
var
|
|
T, NewChild: ICommonTree;
|
|
begin
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd'))); // index 2
|
|
NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
|
|
T.ReplaceChildren(2, 2, NewChild);
|
|
CheckEquals(T.ToStringTree, '(a b c x)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceInMiddle;
|
|
var
|
|
T, NewChild: ICommonTree;
|
|
begin
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c'))); // index 1
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
|
|
NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
|
|
T.ReplaceChildren(1, 1, NewChild);
|
|
CheckEquals(T.ToStringTree, '(a b x d)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceOneWithTwoAtLeft;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
T, NewChildren: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
|
|
NewChildren := Adaptor.GetNilNode as ICommonTree;
|
|
NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x')));
|
|
NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y')));
|
|
T.ReplaceChildren(0, 0, NewChildren);
|
|
CheckEquals(T.ToStringTree, '(a x y c d)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceOneWithTwoAtRight;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
T, NewChildren: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
|
|
NewChildren := Adaptor.GetNilNode as ICommonTree;
|
|
NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x')));
|
|
NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y')));
|
|
T.ReplaceChildren(2, 2, NewChildren);
|
|
CheckEquals(T.ToStringTree, '(a b c x y)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceOneWithTwoInMiddle;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
T, NewChildren: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
|
|
NewChildren := Adaptor.GetNilNode as ICommonTree;
|
|
NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'x')));
|
|
NewChildren.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'y')));
|
|
T.ReplaceChildren(1, 1, NewChildren);
|
|
CheckEquals(T.ToStringTree, '(a b x y d)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceTwoWithOneAtLeft;
|
|
var
|
|
T, NewChild: ICommonTree;
|
|
begin
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
|
|
NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
|
|
T.ReplaceChildren(0, 1, NewChild);
|
|
CheckEquals(T.ToStringTree, '(a x d)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceTwoWithOneAtRight;
|
|
var
|
|
T, NewChild: ICommonTree;
|
|
begin
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'b')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'c')));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(99, 'd')));
|
|
NewChild := TCommonTree.Create(TCommonToken.Create(99, 'x'));
|
|
T.ReplaceChildren(1, 2, NewChild);
|
|
CheckEquals(T.ToStringTree, '(a b x)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceWithNoChildren;
|
|
var
|
|
T, NewChild: ICommonTree;
|
|
Error: Boolean;
|
|
begin
|
|
Exit; // already checked. Avoid exception
|
|
T := TCommonTree.Create(TCommonToken.Create(101));
|
|
NewChild := TCommonTree.Create(TCommonToken.Create(5));
|
|
Error := False;
|
|
try
|
|
T.ReplaceChildren(0, 0, NewChild);
|
|
except
|
|
Error := True;
|
|
end;
|
|
CheckTrue(Error);
|
|
end;
|
|
|
|
procedure TestICommonTree.TestReplaceWithOneChildren;
|
|
var
|
|
T, C0, NewChild: ICommonTree;
|
|
begin
|
|
// assume token type 99 and use text
|
|
T := TCommonTree.Create(TCommonToken.Create(99, 'a'));
|
|
C0 := TCommonTree.Create(TCommonToken.Create(99, 'b'));
|
|
T.AddChild(C0);
|
|
NewChild := TCommonTree.Create(TCommonToken.Create(99, 'c'));
|
|
T.ReplaceChildren(0, 0, NewChild);
|
|
CheckEquals(T.ToStringTree,'(a c)');
|
|
T.SanityCheckParentAndChildIndexes;
|
|
end;
|
|
|
|
procedure TestICommonTree.TestSingleNode;
|
|
var
|
|
T: ICommonTree;
|
|
begin
|
|
T := TCommonTree.Create(TCommonToken.Create(101));
|
|
CheckNull(T.Parent);
|
|
CheckEquals(T.ChildIndex, -1);
|
|
end;
|
|
|
|
function TestICommonTreeNodeStream.CreateCommonTreeNodeStream(
|
|
const T: IANTLRInterface): ITreeNodeStream;
|
|
begin
|
|
Result := TCommonTreeNodeStream.Create(T);
|
|
end;
|
|
|
|
function TestICommonTreeNodeStream.CreateUnBufferedTreeNodeStream(
|
|
const T: IANTLRInterface): ITreeNodeStream;
|
|
begin
|
|
Result := TUnBufferedTreeNodeStream.Create(T);
|
|
end;
|
|
|
|
function TestICommonTreeNodeStream.GetStringOfEntireStreamContentsWithNodeTypesOnly(
|
|
const Nodes: ITreeNodeStream): String;
|
|
var
|
|
Buf: TStringBuilder;
|
|
I, TokenType: Integer;
|
|
T: IANTLRInterface;
|
|
begin
|
|
Buf := TStringBuilder.Create;
|
|
try
|
|
for I := 0 to Nodes.Size - 1 do
|
|
begin
|
|
T := Nodes.LT(I + 1);
|
|
TokenType := Nodes.TreeAdaptor.GetNodeType(T);
|
|
if (TokenType <> TToken.DOWN) and (TokenType <> TToken.UP) then
|
|
begin
|
|
Buf.Append(' ');
|
|
Buf.Append(TokenType)
|
|
end;
|
|
end;
|
|
Result := Buf.ToString;
|
|
finally
|
|
Buf.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.SetUp;
|
|
begin
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TearDown;
|
|
begin
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.Test4Nodes;
|
|
var
|
|
T: ITree;
|
|
Stream: ITreeNodeStream;
|
|
begin
|
|
/// Test a tree with four nodes - ^(101 ^(102 103) 104)
|
|
T := TCommonTree.Create(TCommonToken.Create(101));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
T.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
|
|
Stream := CreateCommonTreeNodeStream(T);
|
|
CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102 103 104');
|
|
CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 3');
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestAoverB;
|
|
var
|
|
T: ITree;
|
|
Stream: ITreeNodeStream;
|
|
begin
|
|
T := TCommonTree.Create(TCommonToken.Create(101));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
|
|
Stream := CreateCommonTreeNodeStream(T);
|
|
CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102');
|
|
CheckEquals(Stream.ToString, ' 101 2 102 3');
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestBufferOverflow;
|
|
var
|
|
Buf, Buf2: TStringBuilder;
|
|
Stream: ITreeNodeStream;
|
|
T: ITree;
|
|
I: Integer;
|
|
begin
|
|
Buf := TStringBuilder.Create;
|
|
Buf2 := TStringBuilder.Create;
|
|
try
|
|
// make ^(101 102 ... n)
|
|
T := TCommonTree.Create(TCommonToken.Create(101));
|
|
Buf.Append(' 101');
|
|
Buf2.Append(' 101');
|
|
Buf2.Append(' ');
|
|
Buf2.Append(TToken.DOWN);
|
|
|
|
for I := 0 to TUnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE + 10 do
|
|
begin
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(102 + I)));
|
|
Buf.Append(' ');
|
|
Buf.Append(102 + I);
|
|
Buf2.Append(' ');
|
|
Buf2.Append(102 + I);
|
|
end;
|
|
Buf2.Append(' ');
|
|
Buf2.Append(TToken.UP);
|
|
|
|
Stream := CreateUnBufferedTreeNodeStream(T);
|
|
CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream), Buf.ToString);
|
|
CheckEquals(Stream.ToString, Buf2.ToString);
|
|
finally
|
|
Buf2.Free;
|
|
Buf.Free;
|
|
end;
|
|
end;
|
|
|
|
/// <summary>
|
|
/// Test what happens when tail hits the end of the buffer, but there
|
|
/// is more room left.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Specifically that would mean that head is not at 0 but has
|
|
/// advanced somewhere to the middle of the lookahead buffer.
|
|
///
|
|
/// Use Consume() to advance N nodes into lookahead. Then use LT()
|
|
/// to load at least INITIAL_LOOKAHEAD_BUFFER_SIZE-N nodes so the
|
|
/// buffer has to wrap.
|
|
/// </remarks>
|
|
procedure TestICommonTreeNodeStream.TestBufferWrap;
|
|
const
|
|
N = 10;
|
|
WrapBy = 4; // wrap around by 4 nodes
|
|
var
|
|
T: ITree;
|
|
I, Remaining: Integer;
|
|
Stream: ITreeNodeStream;
|
|
Node: ITree;
|
|
begin
|
|
// make tree with types: 1 2 ... INITIAL_LOOKAHEAD_BUFFER_SIZE+N
|
|
T := TCommonTree.Create(IToken(nil));
|
|
for I := 0 to TUnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE + N - 1 do
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(I + 1)));
|
|
|
|
// move head to index N
|
|
Stream := CreateUnBufferedTreeNodeStream(T);
|
|
for I := 1 to N do
|
|
begin
|
|
// consume N
|
|
Node := Stream.LT(1) as ITree;
|
|
CheckEquals(Node.TokenType, I);
|
|
Stream.Consume;
|
|
end;
|
|
|
|
// now use LT to lookahead past end of buffer
|
|
Remaining := TUnBufferedTreeNodeStream.INITIAL_LOOKAHEAD_BUFFER_SIZE - N;
|
|
CheckTrue(WrapBy < N);
|
|
for I := 1 to Remaining + WrapBy do
|
|
begin
|
|
// wrap past end of buffer
|
|
Node := Stream.LT(I) as ITree; // look ahead to ith token
|
|
CheckEquals(Node.TokenType, N + I);
|
|
end;
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestFlatList;
|
|
var
|
|
Root: ITree;
|
|
Stream: ITreeNodeStream;
|
|
begin
|
|
Root := TCommonTree.Create(IToken(nil));
|
|
Root.AddChild(TCommonTree.Create(TCommonToken.Create(101)));
|
|
Root.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
Root.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
|
|
Stream := CreateCommonTreeNodeStream(Root);
|
|
CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102 103');
|
|
CheckEquals(Stream.ToString, ' 101 102 103');
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestList;
|
|
var
|
|
Root, T, U: ITree;
|
|
Stream: ITreeNodeStream;
|
|
begin
|
|
Root := TCommonTree.Create(IToken(nil));
|
|
|
|
T := TCommonTree.Create(TCommonToken.Create(101));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
T.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
|
|
U := TCommonTree.Create(TCommonToken.Create(105));
|
|
|
|
Root.AddChild(T);
|
|
Root.AddChild(U);
|
|
|
|
Stream := CreateCommonTreeNodeStream(Root);
|
|
CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101 102 103 104 105');
|
|
CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 3 105');
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestListWithOneNode;
|
|
var
|
|
Root: ITree;
|
|
Stream: ITreeNodeStream;
|
|
begin
|
|
Root := TCommonTree.Create(IToken(nil));
|
|
Root.AddChild(TCommonTree.Create(TCommonToken.Create(101)));
|
|
|
|
Stream := CreateCommonTreeNodeStream(Root);
|
|
CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101');
|
|
CheckEquals(Stream.ToString, ' 101');
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestLT;
|
|
var
|
|
T: ITree;
|
|
Stream: ITreeNodeStream;
|
|
begin
|
|
// ^(101 ^(102 103) 104)
|
|
T := TCommonTree.Create(TCommonToken.Create(101));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(102)));
|
|
T.GetChild(0).AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
T.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
|
|
Stream := CreateCommonTreeNodeStream(T);
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,101);
|
|
CheckEquals((Stream.LT(2) as ITree).TokenType,TToken.DOWN);
|
|
CheckEquals((Stream.LT(3) as ITree).TokenType,102);
|
|
CheckEquals((Stream.LT(4) as ITree).TokenType,TToken.DOWN);
|
|
CheckEquals((Stream.LT(5) as ITree).TokenType,103);
|
|
CheckEquals((Stream.LT(6) as ITree).TokenType,TToken.UP);
|
|
CheckEquals((Stream.LT(7) as ITree).TokenType,104);
|
|
CheckEquals((Stream.LT(8) as ITree).TokenType,TToken.UP);
|
|
CheckEquals((Stream.LT(9) as ITree).TokenType,TToken.EOF);
|
|
// check way ahead
|
|
CheckEquals((Stream.LT(100) as ITree).TokenType,TToken.EOF);
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestMarkRewindEntire;
|
|
var
|
|
R0, R1, R2: ITree;
|
|
Stream: ICommonTreeNodeStream;
|
|
M, K: Integer;
|
|
begin
|
|
// ^(101 ^(102 103 ^(106 107) ) 104 105)
|
|
// stream has 7 real + 6 nav nodes
|
|
// Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
R0.AddChild(R1);
|
|
R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R2 := TCommonTree.Create(TCommonToken.Create(106));
|
|
R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
|
|
R1.AddChild(R2);
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
|
|
|
|
Stream := TCommonTreeNodeStream.Create(R0);
|
|
M := Stream.Mark;
|
|
for K := 1 to 13 do
|
|
begin
|
|
// consume til end
|
|
Stream.LT(1);
|
|
Stream.Consume;
|
|
end;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
|
|
CheckEquals((Stream.LT(-1) as ITree).TokenType,TToken.UP);
|
|
Stream.Rewind(M);
|
|
|
|
for K := 1 to 13 do
|
|
begin
|
|
// consume til end
|
|
Stream.LT(1);
|
|
Stream.Consume;
|
|
end;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
|
|
CheckEquals((Stream.LT(-1) as ITree).TokenType,TToken.UP);
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestMarkRewindInMiddle;
|
|
var
|
|
R0, R1, R2: ITree;
|
|
Stream: ICommonTreeNodeStream;
|
|
M, K: Integer;
|
|
begin
|
|
// ^(101 ^(102 103 ^(106 107) ) 104 105)
|
|
// stream has 7 real + 6 nav nodes
|
|
// Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
R0.AddChild(R1);
|
|
R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R2 := TCommonTree.Create(TCommonToken.Create(106));
|
|
R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
|
|
R1.AddChild(R2);
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
|
|
|
|
Stream := TCommonTreeNodeStream.Create(R0);
|
|
for K := 1 to 7 do
|
|
begin
|
|
// consume til middle
|
|
Stream.Consume;
|
|
end;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,107);
|
|
M := Stream.Mark;
|
|
Stream.Consume; // consume 107
|
|
Stream.Consume; // consume UP
|
|
Stream.Consume; // consume UP
|
|
Stream.Consume; // consume 104
|
|
Stream.Rewind(M);
|
|
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,107);
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,104);
|
|
Stream.Consume;
|
|
// now we're past rewind position
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,105);
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
|
|
CheckEquals((Stream.LT(-1) as ITree).TokenType,TToken.UP);
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestMarkRewindNested;
|
|
var
|
|
R0, R1, R2: ITree;
|
|
Stream: ICommonTreeNodeStream;
|
|
M, M2: Integer;
|
|
begin
|
|
// ^(101 ^(102 103 ^(106 107) ) 104 105)
|
|
// stream has 7 real + 6 nav nodes
|
|
// Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
R0.AddChild(R1);
|
|
R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R2 := TCommonTree.Create(TCommonToken.Create(106));
|
|
R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
|
|
R1.AddChild(R2);
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
|
|
|
|
Stream := TCommonTreeNodeStream.Create(R0);
|
|
M := Stream.Mark; // MARK at start
|
|
Stream.Consume; // consume 101
|
|
Stream.Consume; // consume DN
|
|
M2:= Stream.Mark; // MARK on 102
|
|
Stream.Consume; // consume 102
|
|
Stream.Consume; // consume DN
|
|
Stream.Consume; // consume 103
|
|
Stream.Consume; // consume 106
|
|
Stream.Rewind(M2);
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,102);
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
|
|
Stream.Consume;
|
|
// stop at 103 and rewind to start
|
|
Stream.Rewind(M); // REWIND to 101
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,101);
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,102);
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestNestedPushPop;
|
|
const
|
|
IndexOf102 = 2;
|
|
IndexOf104 = 6;
|
|
IndexOf107 = 12;
|
|
var
|
|
R0, R1, R2, R3: ITree;
|
|
Stream: ICommonTreeNodeStream;
|
|
K: Integer;
|
|
begin
|
|
// ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109)
|
|
// stream has 9 real + 8 nav nodes
|
|
// Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R0.AddChild(R1);
|
|
R2 := TCommonTree.Create(TCommonToken.Create(104));
|
|
R2.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
|
|
R0.AddChild(R2);
|
|
R3 := TCommonTree.Create(TCommonToken.Create(106));
|
|
R3.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
|
|
R0.AddChild(R3);
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(108)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(109)));
|
|
|
|
Stream := TCommonTreeNodeStream.Create(R0);
|
|
CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3');
|
|
|
|
// Assume we want to hit node 107 and then "call 102", which
|
|
// calls 104, then return
|
|
for K := 1 to IndexOf107 do
|
|
// consume til 107 node
|
|
Stream.Consume;
|
|
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,107);
|
|
// CALL 102
|
|
Stream.Push(IndexOf102);
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,102);
|
|
Stream.Consume; // consume 102
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
|
|
Stream.Consume; // consume DN
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,103);
|
|
Stream.Consume; // consume 103
|
|
|
|
// CALL 104
|
|
Stream.Push(IndexOf104);
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,104);
|
|
Stream.Consume; // consume 104
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
|
|
Stream.Consume; // consume DN
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,105);
|
|
Stream.Consume; // consume 1045
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
|
|
|
|
// RETURN (to UP node in 102 subtree)
|
|
Stream.Pop;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
|
|
|
|
// RETURN (to empty stack)
|
|
Stream.Pop;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,107);
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestPushPop;
|
|
const
|
|
IndexOf102 = 2;
|
|
IndexOf107 = 12;
|
|
var
|
|
R0, R1, R2, R3: ITree;
|
|
Stream: ICommonTreeNodeStream;
|
|
K: Integer;
|
|
begin
|
|
// ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109)
|
|
// stream has 9 real + 8 nav nodes
|
|
// Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R0.AddChild(R1);
|
|
R2 := TCommonTree.Create(TCommonToken.Create(104));
|
|
R2.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
|
|
R0.AddChild(R2);
|
|
R3 := TCommonTree.Create(TCommonToken.Create(106));
|
|
R3.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
|
|
R0.AddChild(R3);
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(108)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(109)));
|
|
|
|
Stream := TCommonTreeNodeStream.Create(R0);
|
|
CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3');
|
|
|
|
// Assume we want to hit node 107 and then "call 102" then return
|
|
for K := 1 to IndexOf107 do
|
|
// consume til 107 node
|
|
Stream.Consume;
|
|
|
|
// CALL 102
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,107);
|
|
Stream.Push(IndexOf102);
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,102);
|
|
Stream.Consume; // consume 102
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
|
|
Stream.Consume; // consume DN
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,103);
|
|
Stream.Consume; // consume 103
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
|
|
// RETURN
|
|
Stream.Pop;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,107);
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestPushPopFromEOF;
|
|
const
|
|
IndexOf102 = 2;
|
|
IndexOf104 = 6;
|
|
var
|
|
R0, R1, R2, R3: ITree;
|
|
Stream: ICommonTreeNodeStream;
|
|
begin
|
|
// ^(101 ^(102 103) ^(104 105) ^(106 107) 108 109)
|
|
// stream has 9 real + 8 nav nodes
|
|
// Sequence of types: 101 DN 102 DN 103 UP 104 DN 105 UP 106 DN 107 UP 108 109 UP
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R0.AddChild(R1);
|
|
R2 := TCommonTree.Create(TCommonToken.Create(104));
|
|
R2.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
|
|
R0.AddChild(R2);
|
|
R3 := TCommonTree.Create(TCommonToken.Create(106));
|
|
R3.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
|
|
R0.AddChild(R3);
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(108)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(109)));
|
|
|
|
Stream := TCommonTreeNodeStream.Create(R0);
|
|
CheckEquals(Stream.ToString, ' 101 2 102 2 103 3 104 2 105 3 106 2 107 3 108 109 3');
|
|
|
|
while (Stream.LA(1) <> TToken.EOF) do
|
|
Stream.Consume;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
|
|
|
|
// CALL 102
|
|
Stream.Push(IndexOf102);
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,102);
|
|
Stream.Consume; // consume 102
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
|
|
Stream.Consume; // consume DN
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,103);
|
|
Stream.Consume; // consume 103
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
|
|
// RETURN (to empty stack)
|
|
Stream.Pop;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
|
|
|
|
// CALL 104
|
|
Stream.Push(IndexOf104);
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,104);
|
|
Stream.Consume; // consume 104
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.DOWN);
|
|
Stream.Consume; // consume DN
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,105);
|
|
Stream.Consume; // consume 105
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.UP);
|
|
// RETURN (to empty stack)
|
|
Stream.Pop;
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,TToken.EOF);
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestSeek;
|
|
var
|
|
R0, R1, R2: ITree;
|
|
Stream: ICommonTreeNodeStream;
|
|
begin
|
|
// ^(101 ^(102 103 ^(106 107) ) 104 105)
|
|
// stream has 7 real + 6 nav nodes
|
|
// Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
R0.AddChild(R1);
|
|
R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R2 := TCommonTree.Create(TCommonToken.Create(106));
|
|
R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
|
|
R1.AddChild(R2);
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
|
|
|
|
Stream := TCommonTreeNodeStream.Create(R0);
|
|
Stream.Consume; // consume 101
|
|
Stream.Consume; // consume DN
|
|
Stream.Consume; // consume 102
|
|
Stream.Seek(7); // seek to 107
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,107);
|
|
Stream.Consume; // consume 107
|
|
Stream.Consume; // consume UP
|
|
Stream.Consume; // consume UP
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,104);
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestSeekFromStart;
|
|
var
|
|
R0, R1, R2: ITree;
|
|
Stream: ICommonTreeNodeStream;
|
|
begin
|
|
// ^(101 ^(102 103 ^(106 107) ) 104 105)
|
|
// stream has 7 real + 6 nav nodes
|
|
// Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
R1 := TCommonTree.Create(TCommonToken.Create(102));
|
|
R0.AddChild(R1);
|
|
R1.AddChild(TCommonTree.Create(TCommonToken.Create(103)));
|
|
R2 := TCommonTree.Create(TCommonToken.Create(106));
|
|
R2.AddChild(TCommonTree.Create(TCommonToken.Create(107)));
|
|
R1.AddChild(R2);
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(104)));
|
|
R0.AddChild(TCommonTree.Create(TCommonToken.Create(105)));
|
|
|
|
Stream := TCommonTreeNodeStream.Create(R0);
|
|
Stream.Seek(7); // seek to 107
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,107);
|
|
Stream.Consume; // consume 107
|
|
Stream.Consume; // consume UP
|
|
Stream.Consume; // consume UP
|
|
CheckEquals((Stream.LT(1) as ITree).TokenType,104);
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestSingleNode;
|
|
var
|
|
T: ITree;
|
|
Stream: ITreeNodeStream;
|
|
begin
|
|
T := TCommonTree.Create(TCommonToken.Create(101));
|
|
Stream := CreateCommonTreeNodeStream(T);
|
|
CheckEquals(GetStringOfEntireStreamContentsWithNodeTypesOnly(Stream),' 101');
|
|
CheckEquals(Stream.ToString, ' 101');
|
|
end;
|
|
|
|
procedure TestICommonTreeNodeStream.TestStackStretch;
|
|
var
|
|
R0: ICommonTree;
|
|
Stream: ICommonTreeNodeStream;
|
|
I: Integer;
|
|
begin
|
|
// make more than INITIAL_CALL_STACK_SIZE pushes
|
|
R0 := TCommonTree.Create(TCommonToken.Create(101));
|
|
Stream := TCommonTreeNodeStream.Create(R0);
|
|
|
|
// go 1 over initial size
|
|
for I := 1 to TCommonTreeNodeStream.INITIAL_CALL_STACK_SIZE + 1 do
|
|
Stream.Push(I);
|
|
|
|
CheckEquals(Stream.Pop, 10);
|
|
CheckEquals(Stream.Pop, 9);
|
|
end;
|
|
|
|
function TestIRewriteRuleXxxxStream.CreateToken(const TokenType: Integer;
|
|
const Text: String): IToken;
|
|
begin
|
|
Result := TCommonToken.Create(TokenType, Text);
|
|
end;
|
|
|
|
function TestIRewriteRuleXxxxStream.CreateTokenList(
|
|
const Count: Integer): IList<IToken>;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := TList<IToken>.Create;
|
|
for I := 0 to Count - 1 do
|
|
Result.Add(TCommonToken.Create(I + 1,'test token ' + IntToStr(I + 1)
|
|
+ ' without any real context'));
|
|
end;
|
|
|
|
function TestIRewriteRuleXxxxStream.CreateTree(const Token: IToken): ITree;
|
|
begin
|
|
Result := TCommonTree.Create(Token);
|
|
end;
|
|
|
|
function TestIRewriteRuleXxxxStream.CreateTreeAdaptor: ITreeAdaptor;
|
|
begin
|
|
Result := TCommonTreeAdaptor.Create;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.SetUp;
|
|
begin
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TearDown;
|
|
begin
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRewriteRuleNodeStreamConstructors;
|
|
var
|
|
NodeTest1, NodeTest2, NodeTest3: IRewriteRuleNodeStream;
|
|
begin
|
|
NodeTest1 := TRewriteRuleNodeStream.Create(CreateTreeAdaptor,
|
|
'RewriteRuleNodeStream test1');
|
|
|
|
NodeTest2 := TRewriteRuleNodeStream.Create(CreateTreeAdaptor,
|
|
'RewriteRuleNodeStream test2',
|
|
CreateToken(1,'test token without any real context'));
|
|
|
|
NodeTest3 := TRewriteRuleNodeStream.Create(CreateTreeAdaptor,
|
|
'RewriteRuleNodeStream test3', CreateTokenList(4));
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRewriteRuleSubtreeStreamConstructors;
|
|
var
|
|
SubtreeTest1, SubtreeTest2, SubtreeTest3: IRewriteRuleSubtreeStream;
|
|
begin
|
|
SubtreeTest1 := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor,
|
|
'RewriteRuleSubtreeStream test1');
|
|
|
|
SubtreeTest2 := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor,
|
|
'RewriteRuleSubtreeStream test2',
|
|
CreateToken(1,'test token without any real context'));
|
|
|
|
SubtreeTest3 := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor,
|
|
'RewriteRuleSubtreeStream test3', CreateTokenList(4));
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRewriteRuleTokenStreamConstructors;
|
|
var
|
|
TokenTest1, TokenTest2, TokenTest3: IRewriteRuleTokenStream;
|
|
begin
|
|
TokenTest1 := TRewriteRuleTokenStream.Create(CreateTreeAdaptor,
|
|
'RewriteRuleTokenStream test1');
|
|
|
|
TokenTest2 := TRewriteRuleTokenStream.Create(CreateTreeAdaptor,
|
|
'RewriteRuleTokenStream test2',
|
|
CreateToken(1, 'test token without any real context'));
|
|
|
|
TokenTest3 := TRewriteRuleTokenStream.Create(CreateTreeAdaptor,
|
|
'RewriteRuleTokenStream test3', CreateTokenList(4));
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWhileEmpty1;
|
|
const
|
|
Description = 'RewriteRuleNodeStream test';
|
|
var
|
|
NodeTest: IRewriteRuleNodeStream;
|
|
begin
|
|
ExpectedException := ERewriteEmptyStreamException;
|
|
NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, Description);
|
|
|
|
CheckFalse(NodeTest.HasNext);
|
|
CheckEquals(Description, NodeTest.Description);
|
|
CheckEquals(NodeTest.Size, 0);
|
|
NodeTest.Reset;
|
|
CheckEquals(NodeTest.Size, 0);
|
|
NodeTest.NextNode;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWhileEmpty2;
|
|
const
|
|
Description = 'RewriteRuleNodeStream test';
|
|
var
|
|
NodeTest: IRewriteRuleNodeStream;
|
|
begin
|
|
ExpectedException := ERewriteEmptyStreamException;
|
|
NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, Description);
|
|
NodeTest.NextTree;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRNodeStreamBehaviourWithElements;
|
|
var
|
|
NodeTest: IRewriteRuleNodeStream;
|
|
Token1, Token2: IToken;
|
|
Tree1, Tree2: ITree;
|
|
ReturnedTree: ICommonTree;
|
|
begin
|
|
ExpectedException := ERewriteCardinalityException;
|
|
NodeTest := TRewriteRuleNodeStream.Create(CreateTreeAdaptor, 'RewriteRuleNodeStream test');
|
|
Token1 := CreateToken(1, 'test token without any real context');
|
|
Tree1 := CreateTree(Token1);
|
|
|
|
// Test Add()
|
|
NodeTest.Add(Tree1);
|
|
CheckEquals(NodeTest.Size, 1);
|
|
CheckTrue(NodeTest.HasNext);
|
|
|
|
// Test NextNode()
|
|
ReturnedTree := NodeTest.NextNode as ICommoNTree;
|
|
CheckEquals(ReturnedTree.TokenType, Tree1.TokenType);
|
|
CheckEquals(NodeTest.Size, 1);
|
|
CheckFalse(NodeTest.HasNext);
|
|
NodeTest.Reset;
|
|
CheckEquals(NodeTest.Size, 1);
|
|
CheckTrue(NodeTest.HasNext);
|
|
|
|
// Test NextTree()
|
|
ReturnedTree := NodeTest.NextTree as ICommonTree;
|
|
Check(SameObj(Token1, ReturnedTree.Token));
|
|
CheckEquals(NodeTest.Size, 1);
|
|
CheckFalse(NodeTest.HasNext);
|
|
NodeTest.Reset;
|
|
CheckEquals(NodeTest.Size, 1);
|
|
CheckTrue(NodeTest.HasNext);
|
|
|
|
// Test, what happens with two elements
|
|
Token2 := CreateToken(2, 'test token without any real context');
|
|
Tree2 := CreateTree(Token2);
|
|
NodeTest.Add(Tree2);
|
|
CheckEquals(NodeTest.Size, 2);
|
|
CheckTrue(NodeTest.HasNext);
|
|
ReturnedTree := NodeTest.NextTree as ICommonTree;
|
|
Check(SameObj(Token1, ReturnedTree.Token));
|
|
CheckEquals(NodeTest.Size, 2);
|
|
CheckTrue(NodeTest.HasNext);
|
|
ReturnedTree := NodeTest.NextTree as ICommonTree;
|
|
Check(SameObj(Token2, ReturnedTree.Token));
|
|
CheckFalse(NodeTest.HasNext);
|
|
|
|
// Test exception
|
|
NodeTest.NextTree;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWhileEmpty1;
|
|
const
|
|
Description = 'RewriteRuleSubtreeStream test';
|
|
var
|
|
SubtreeTest: IRewriteRuleSubtreeStream;
|
|
begin
|
|
ExpectedException := ERewriteEmptyStreamException;
|
|
SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, Description);
|
|
|
|
CheckFalse(SubtreeTest.HasNext);
|
|
CheckEquals(Description, SubtreeTest.Description);
|
|
CheckEquals(SubtreeTest.Size, 0);
|
|
SubtreeTest.Reset;
|
|
CheckEquals(SubtreeTest.Size, 0);
|
|
SubtreeTest.NextNode;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWhileEmpty2;
|
|
const
|
|
Description = 'RewriteRuleSubtreeStream test';
|
|
var
|
|
SubtreeTest: IRewriteRuleSubtreeStream;
|
|
begin
|
|
ExpectedException := ERewriteEmptyStreamException;
|
|
SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, Description);
|
|
SubtreeTest.NextTree;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRSubtreeStreamBehaviourWithElements;
|
|
var
|
|
SubtreeTest: IRewriteRuleSubtreeStream;
|
|
Token1, Token2: IToken;
|
|
Tree1, Tree2: ITree;
|
|
ReturnedTree: ICommonTree;
|
|
begin
|
|
ExpectedException := ERewriteCardinalityException;
|
|
SubtreeTest := TRewriteRuleSubtreeStream.Create(CreateTreeAdaptor, 'RewriteRuleSubtreeStream test');
|
|
Token1 := CreateToken(1, 'test token without any real context');
|
|
Tree1 := CreateTree(Token1);
|
|
|
|
// Test Add()
|
|
SubtreeTest.Add(Tree1);
|
|
CheckEquals(SubtreeTest.Size, 1);
|
|
CheckTrue(SubtreeTest.HasNext);
|
|
|
|
// Test NextNode()
|
|
Check(SameObj(SubtreeTest.NextNode, Tree1));
|
|
CheckEquals(SubtreeTest.Size, 1);
|
|
CheckFalse(SubtreeTest.HasNext);
|
|
SubtreeTest.Reset;
|
|
CheckEquals(SubtreeTest.Size, 1);
|
|
CheckTrue(SubtreeTest.HasNext);
|
|
|
|
// Test NextTree()
|
|
ReturnedTree := SubtreeTest.NextTree as ICommonTree;
|
|
Check(SameObj(Token1, ReturnedTree.Token));
|
|
CheckEquals(SubtreeTest.Size, 1);
|
|
CheckFalse(SubtreeTest.HasNext);
|
|
SubtreeTest.Reset;
|
|
CheckEquals(SubtreeTest.Size, 1);
|
|
CheckTrue(SubtreeTest.HasNext);
|
|
|
|
// Test, what happens with two elements
|
|
Token2 := CreateToken(2, 'test token without any real context');
|
|
Tree2 := CreateTree(Token2);
|
|
SubtreeTest.Add(Tree2);
|
|
CheckEquals(SubtreeTest.Size, 2);
|
|
CheckTrue(SubtreeTest.HasNext);
|
|
ReturnedTree := SubtreeTest.NextTree as ICommonTree;
|
|
Check(SameObj(Token1, ReturnedTree.Token));
|
|
CheckEquals(SubtreeTest.Size, 2);
|
|
CheckTrue(SubtreeTest.HasNext);
|
|
ReturnedTree := SubtreeTest.NextTree as ICommonTree;
|
|
Check(SameObj(Token2, ReturnedTree.Token));
|
|
CheckFalse(SubtreeTest.HasNext);
|
|
|
|
// Test exception
|
|
SubtreeTest.NextTree;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty1;
|
|
const
|
|
Description = 'RewriteRuleTokenStream test';
|
|
var
|
|
TokenTest: IRewriteRuleTokenStream;
|
|
begin
|
|
ExpectedException := ERewriteEmptyStreamException;
|
|
TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description);
|
|
|
|
CheckFalse(TokenTest.HasNext);
|
|
CheckEquals(Description, TokenTest.Description);
|
|
CheckEquals(TokenTest.Size, 0);
|
|
TokenTest.Reset;
|
|
CheckEquals(TokenTest.Size, 0);
|
|
TokenTest.NextNode;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty2;
|
|
const
|
|
Description = 'RewriteRuleTokenStream test';
|
|
var
|
|
TokenTest: IRewriteRuleTokenStream;
|
|
begin
|
|
ExpectedException := ERewriteEmptyStreamException;
|
|
TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description);
|
|
TokenTest.NextTree;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWhileEmpty3;
|
|
const
|
|
Description = 'RewriteRuleTokenStream test';
|
|
var
|
|
TokenTest: IRewriteRuleTokenStream;
|
|
begin
|
|
ExpectedException := ERewriteEmptyStreamException;
|
|
TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, Description);
|
|
TokenTest.NextToken;
|
|
end;
|
|
|
|
procedure TestIRewriteRuleXxxxStream.TestRRTokenStreamBehaviourWithElements;
|
|
var
|
|
TokenTest: IRewriteRuleTokenStream;
|
|
Token1, Token2, ReturnedToken: IToken;
|
|
Tree: ICommonTree;
|
|
begin
|
|
ExpectedException := ERewriteCardinalityException;
|
|
TokenTest := TRewriteRuleTokenStream.Create(CreateTreeAdaptor, 'RewriteRuleTokenStream test');
|
|
Token1 := CreateToken(1, 'test token without any real context');
|
|
|
|
// Test Add()
|
|
TokenTest.Add(Token1);
|
|
CheckEquals(TokenTest.Size, 1);
|
|
CheckTrue(TokenTest.HasNext);
|
|
|
|
// Test NextNode()
|
|
Tree := TokenTest.NextNode as ICommonTree;
|
|
Check(SameObj(Tree.Token, Token1));
|
|
CheckEquals(TokenTest.Size, 1);
|
|
CheckFalse(TokenTest.HasNext);
|
|
TokenTest.Reset;
|
|
CheckEquals(TokenTest.Size, 1);
|
|
CheckTrue(TokenTest.HasNext);
|
|
|
|
// Test NextToken()
|
|
ReturnedToken := TokenTest.NextToken;
|
|
Check(SameObj(Token1, ReturnedToken));
|
|
CheckEquals(TokenTest.Size, 1);
|
|
CheckFalse(TokenTest.HasNext);
|
|
TokenTest.Reset;
|
|
CheckEquals(TokenTest.Size, 1);
|
|
CheckTrue(TokenTest.HasNext);
|
|
|
|
// Test NextTree()
|
|
ReturnedToken := TokenTest.NextTree as IToken;
|
|
Check(SameObj(Token1, ReturnedToken));
|
|
CheckEquals(TokenTest.Size, 1);
|
|
CheckFalse(TokenTest.HasNext);
|
|
TokenTest.Reset;
|
|
CheckEquals(TokenTest.Size, 1);
|
|
CheckTrue(TokenTest.HasNext);
|
|
|
|
// Test, what happens with two elements
|
|
Token2 := CreateToken(2, 'test token without any real context');
|
|
TokenTest.Add(Token2);
|
|
CheckEquals(TokenTest.Size, 2);
|
|
CheckTrue(TokenTest.HasNext);
|
|
ReturnedToken := TokenTest.NextToken;
|
|
Check(SameObj(Token1, ReturnedToken));
|
|
CheckEquals(TokenTest.Size, 2);
|
|
CheckTrue(TokenTest.HasNext);
|
|
ReturnedToken := TokenTest.NextToken;
|
|
Check(SameObj(Token2, ReturnedToken));
|
|
CheckFalse(TokenTest.HasNext);
|
|
|
|
// Test exception
|
|
TokenTest.NextToken;
|
|
end;
|
|
|
|
constructor TestITreeWizard.Create(MethodName: String);
|
|
const
|
|
TOKENS: array [0..11] of String = ('', '', '', '', '', 'A', 'B', 'C', 'D', 'E', 'ID', 'VAR');
|
|
var
|
|
I: Integer;
|
|
begin
|
|
inherited;
|
|
SetLength(FTokens,Length(TOKENS));
|
|
for I := 0 to Length(TOKENS) - 1 do
|
|
FTokens[I] := TOKENS[I];
|
|
end;
|
|
|
|
procedure TestITreeWizard.SetUp;
|
|
begin
|
|
end;
|
|
|
|
procedure TestITreeWizard.TearDown;
|
|
begin
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestDoubleLevelTree;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A (B C) (B D) E)') as ICommonTree;
|
|
CheckEquals(T.ToStringTree, '(A (B C) (B D) E)');
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestEquals;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T1, T2: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T1 := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
|
|
T2 := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
|
|
CheckTrue(Wiz.Equals(T1, T2, Adaptor));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestEqualsWithMismatchedText;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T1, T2: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T1 := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree;
|
|
T2 := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
|
|
CheckFalse(Wiz.Equals(T1, T2, Adaptor));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestEqualsWithText;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T1, T2: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T1 := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree;
|
|
T2 := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree;
|
|
CheckTrue(Wiz.Equals(T1, T2, Adaptor));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestFindPattern;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Subtrees, Elements: IList<IANTLRInterface>;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C (A[foo] B[bar]) (D (A[big] B[dog])))') as ICommonTree;
|
|
Subtrees := Wiz.Find(T, '(A B)');
|
|
Elements := Subtrees;
|
|
CheckEquals('[foo, big]', TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestInvalidListTree;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('A B C') as ICommonTree;
|
|
CheckNull(T);
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestListTree;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(nil A B C)') as ICommonTree;
|
|
CheckEquals(T.ToStringTree, 'A B C');
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestNoRepeatsIndex;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
M: IDictionary<Integer, IList<IANTLRInterface>>;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C D)') as ICommonTree;
|
|
M := Wiz.Index(T);
|
|
CheckEquals('{5=[A], 8=[D], 7=[C], 6=[B]}' ,TCollectionUtils.DictionaryToString(M));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestNoRepeatsVisit;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Elements: IList<IANTLRInterface>;
|
|
Visitor: IContextVisitor;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C D)') as ICommonTree;
|
|
Elements := TList<IANTLRInterface>.Create;
|
|
Visitor := TRecordAllElementsVisitor.Create(Elements);
|
|
Wiz.Visit(T, Wiz.GetTokenType('B'), Visitor);
|
|
CheckEquals('[B]' ,TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestNoRepeatsVisit2;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Elements: IList<IANTLRInterface>;
|
|
Visitor: IContextVisitor;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
|
|
Elements := TList<IANTLRInterface>.Create;
|
|
Visitor := TRecordAllElementsVisitor.Create(Elements);
|
|
Wiz.Visit(T, Wiz.GetTokenType('C'), Visitor);
|
|
CheckEquals('[C]' ,TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestParse;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
|
|
CheckTrue(Wiz.Parse(T, '(A B C)'));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestParseFlatTree;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(nil A B C)') as ICommonTree;
|
|
CheckTrue(Wiz.Parse(T, '(nil A B C)'));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestParseLabels;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Labels: IDictionary<String, IANTLRInterface>;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
|
|
Labels := TDictionary<String, IANTLRInterface>.Create;
|
|
CheckTrue(Wiz.Parse(T, '(%a:A %b:B %c:C)', Labels));
|
|
CheckEquals('A', Labels['a'].ToString);
|
|
CheckEquals('B', Labels['b'].ToString);
|
|
CheckEquals('C', Labels['c'].ToString);
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestParseLabelsAndTestText;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Labels: IDictionary<String, IANTLRInterface>;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B[foo] C)') as ICommonTree;
|
|
Labels := TDictionary<String, IANTLRInterface>.Create;
|
|
CheckTrue(Wiz.Parse(T, '(%a:A %b:B[foo] %c:C)', Labels));
|
|
CheckEquals('A', Labels['a'].ToString);
|
|
CheckEquals('foo', Labels['b'].ToString);
|
|
CheckEquals('C', Labels['c'].ToString);
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestParseLabelsInNestedTree;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Labels: IDictionary<String, IANTLRInterface>;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A (B C) (D E))') as ICommonTree;
|
|
Labels := TDictionary<String, IANTLRInterface>.Create;
|
|
CheckTrue(Wiz.Parse(T, '(%a:A (%b:B %c:C) (%d:D %e:E) )', Labels));
|
|
CheckEquals('A', Labels['a'].ToString);
|
|
CheckEquals('B', Labels['b'].ToString);
|
|
CheckEquals('C', Labels['c'].ToString);
|
|
CheckEquals('D', Labels['d'].ToString);
|
|
CheckEquals('E', Labels['e'].ToString);
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestParseSingleNode;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('A') as ICommonTree;
|
|
CheckTrue(Wiz.Parse(T, 'A'));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestParseWithText;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B[foo] C[bar])') as ICommonTree;
|
|
// C pattern has no text arg so despite [bar] in t, no need
|
|
// to match text--check structure only.
|
|
CheckTrue(Wiz.Parse(T, '(A B[foo] C)'));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestParseWithTextFails;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
|
|
CheckFalse(Wiz.Parse(T, '(A[foo] B C)'));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestParseWithWildcardLabels;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Labels: IDictionary<String, IANTLRInterface>;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
|
|
Labels := TDictionary<String, IANTLRInterface>.Create;
|
|
CheckTrue(Wiz.Parse(T, '(A %b:. %c:.)', Labels));
|
|
CheckEquals('B', Labels['b'].ToString);
|
|
CheckEquals('C', Labels['c'].ToString);
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestRepeatsIndex;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
M: IDictionary<Integer, IList<IANTLRInterface>>;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
|
|
M := Wiz.Index(T);
|
|
CheckEquals('{5=[A, A], 8=[D, D], 7=[C], 6=[B, B, B]}' ,TCollectionUtils.DictionaryToString(M));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestRepeatsVisit;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Elements: IList<IANTLRInterface>;
|
|
Visitor: IContextVisitor;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
|
|
Elements := TList<IANTLRInterface>.Create;
|
|
Visitor := TRecordAllElementsVisitor.Create(Elements);
|
|
Wiz.Visit(T, Wiz.GetTokenType('B'), Visitor);
|
|
CheckEquals('[B, B, B]' ,TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestRepeatsVisit2;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Elements: IList<IANTLRInterface>;
|
|
Visitor: IContextVisitor;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
|
|
Elements := TList<IANTLRInterface>.Create;
|
|
Visitor := TRecordAllElementsVisitor.Create(Elements);
|
|
Wiz.Visit(T, Wiz.GetTokenType('A'), Visitor);
|
|
CheckEquals('[A, A]' ,TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestRepeatsVisitWithContext;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Elements: IList<IANTLRInterface>;
|
|
Visitor: IContextVisitor;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
|
|
Elements := TList<IANTLRInterface>.Create;
|
|
Visitor := TTest1ContextVisitor.Create(Adaptor, Elements);
|
|
Wiz.Visit(T, Wiz.GetTokenType('B'), Visitor);
|
|
CheckEquals('[B@A[0], B@A[1], B@A[2]]', TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestRepeatsVisitWithNullParentAndContext;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Elements: IList<IANTLRInterface>;
|
|
Visitor: IContextVisitor;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B (A C B) B D D)') as ICommonTree;
|
|
Elements := TList<IANTLRInterface>.Create;
|
|
Visitor := TTest1ContextVisitor.Create(Adaptor, Elements);
|
|
Wiz.Visit(T, Wiz.GetTokenType('A'), Visitor);
|
|
CheckEquals('[A@nil[0], A@A[1]]', TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestSingleLevelTree;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C D)') as ICommonTree;
|
|
CheckEquals(T.ToStringTree, '(A B C D)');
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestSingleNode;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('ID') as ICommonTree;
|
|
CheckEquals(T.ToStringTree, 'ID');
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestSingleNodeIndex;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
M: IDictionary<Integer, IList<IANTLRInterface>>;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('ID') as ICommonTree;
|
|
M := Wiz.Index(T);
|
|
CheckEquals('{10=[ID]}' ,TCollectionUtils.DictionaryToString(M));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestSingleNodeTree;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A)') as ICommonTree;
|
|
CheckEquals(T.ToStringTree, 'A');
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestSingleNodeWithArg;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('ID[foo]') as ICommonTree;
|
|
CheckEquals(T.ToStringTree, 'foo');
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestVisitPattern;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Elements: IList<IANTLRInterface>;
|
|
Visitor: IContextVisitor;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C (A B) D)') as ICommonTree;
|
|
Elements := TList<IANTLRInterface>.Create;
|
|
Visitor := TRecordAllElementsVisitor.Create(Elements);
|
|
Wiz.Visit(T, '(A B)', Visitor);
|
|
CheckEquals('[A]', TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestVisitPatternMultiple;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Elements: IList<IANTLRInterface>;
|
|
Visitor: IContextVisitor;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C (A B) (D (A B)))') as ICommonTree;
|
|
Elements := TList<IANTLRInterface>.Create;
|
|
Visitor := TTest1ContextVisitor.Create(Adaptor, Elements);
|
|
Wiz.Visit(T, '(A B)', Visitor);
|
|
CheckEquals('[A@A[2], A@D[0]]', TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestVisitPatternMultipleWithLabels;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
Elements: IList<IANTLRInterface>;
|
|
Visitor: IContextVisitor;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C (A[foo] B[bar]) (D (A[big] B[dog])))') as ICommonTree;
|
|
Elements := TList<IANTLRInterface>.Create;
|
|
Visitor := TTest2ContextVisitor.Create(Adaptor, Elements);
|
|
Wiz.Visit(T, '(%a:A %b:B)', Visitor);
|
|
CheckEquals('[foo@A[2]foo&bar, big@D[0]big&dog]', TCollectionUtils.ListToString(Elements));
|
|
end;
|
|
|
|
procedure TestITreeWizard.TestWildcard;
|
|
var
|
|
Adaptor: ITreeAdaptor;
|
|
Wiz: ITreeWizard;
|
|
T: ICommonTree;
|
|
begin
|
|
Adaptor := TCommonTreeAdaptor.Create;
|
|
Wiz := TTreeWizard.Create(Adaptor, FTokens);
|
|
T := Wiz.CreateTreeOrNode('(A B C)') as ICommonTree;
|
|
CheckTrue(Wiz.Parse(T, '(A . .)'));
|
|
end;
|
|
|
|
{ TestITreeWizard.TRecordAllElementsVisitor }
|
|
|
|
constructor TestITreeWizard.TRecordAllElementsVisitor.Create(
|
|
const AList: IList<IANTLRInterface>);
|
|
begin
|
|
inherited Create;
|
|
FList := AList;
|
|
end;
|
|
|
|
procedure TestITreeWizard.TRecordAllElementsVisitor.Visit(
|
|
const T: IANTLRInterface);
|
|
begin
|
|
FList.Add(T);
|
|
end;
|
|
|
|
{ TestITreeWizard.TTest1ContextVisitor }
|
|
|
|
constructor TestITreeWizard.TTest1ContextVisitor.Create(
|
|
const AAdaptor: ITreeAdaptor; const AList: IList<IANTLRInterface>);
|
|
begin
|
|
inherited Create;
|
|
FAdaptor := AAdaptor;
|
|
FList := AList;
|
|
end;
|
|
|
|
procedure TestITreeWizard.TTest1ContextVisitor.Visit(const T,
|
|
Parent: IANTLRInterface; const ChildIndex: Integer;
|
|
const Labels: IDictionary<String, IANTLRInterface>);
|
|
var
|
|
S: String;
|
|
begin
|
|
S := FAdaptor.GetNodeText(T) + '@';
|
|
if Assigned(Parent) then
|
|
S := S + FAdaptor.GetNodeText(Parent)
|
|
else
|
|
S := S + 'nil';
|
|
FList.Add(TANTLRString.Create(S + '[' + IntToStr(ChildIndex) + ']'));
|
|
end;
|
|
|
|
{ TestITreeWizard.TTest2ContextVisitor }
|
|
|
|
constructor TestITreeWizard.TTest2ContextVisitor.Create(
|
|
const AAdaptor: ITreeAdaptor; const AList: IList<IANTLRInterface>);
|
|
begin
|
|
inherited Create;
|
|
FAdaptor := AAdaptor;
|
|
FList := AList;
|
|
end;
|
|
|
|
procedure TestITreeWizard.TTest2ContextVisitor.Visit(const T,
|
|
Parent: IANTLRInterface; const ChildIndex: Integer;
|
|
const Labels: IDictionary<String, IANTLRInterface>);
|
|
var
|
|
S: String;
|
|
begin
|
|
S := FAdaptor.GetNodeText(T) + '@';
|
|
if Assigned(Parent) then
|
|
S := S + FAdaptor.GetNodeText(Parent)
|
|
else
|
|
S := S + 'nil';
|
|
FList.Add(TANTLRString.Create(S + '[' + IntToStr(ChildIndex) + ']'
|
|
+ Labels['a'].ToString + '&' + Labels['b'].ToString));
|
|
end;
|
|
|
|
initialization
|
|
// Register any test cases with the test runner
|
|
RegisterTest(TestICommonTree.Suite);
|
|
RegisterTest(TestICommonTreeNodeStream.Suite);
|
|
RegisterTest(TestIRewriteRuleXxxxStream.Suite);
|
|
RegisterTest(TestITreeWizard.Suite);
|
|
end.
|
|
|