{
Этот исходный текст является частью Продвинутого векторного транслятора.
Copyright © 2017 Малик Разработчик
Это свободная программа: вы можете перераспространять её и/или
изменять её на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она может быть полезна,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.
}
unit TranTree;
{$MODE DELPHI,EXTENDEDSYNTAX ON}
interface
uses
Lang, Utils, TranIntf;
{$ASMMODE INTEL,CALLING REGISTER,INLINE ON,GOTO ON}
{$H+,I-,J-,M-,Q-,R-,T-}
type
SyntaxNode = interface;
SyntaxTree = interface;
TranslatorSyntaxNode = class;
TranslatorSyntaxTree = class;
TranslatorSyntaxNode_Class = class of TranslatorSyntaxNode;
SyntaxNode = interface(Node) ['{2187DBA7-8D82-42DE-95E7-6B43015BBA93}']
procedure clearData();
procedure setPosition(position: int);
procedure setValue(value: int);
procedure setAssociate(associate: _Interface);
procedure setDataType(dataType: TypeDescriptor);
procedure setDataAssociate(position, value: int;
dataType: TypeDescriptor; associate: _Interface);
procedure setGoAlwaysToNode(goAlwaysToNode: SyntaxNode);
procedure setGoIfTrueToNode(goIfTrueToNode: SyntaxNode);
procedure setGoIfFalseToNode(goIfFalseToNode: SyntaxNode);
procedure setDataGoToNode(ifTrue, ifFalse: SyntaxNode);
function getLabelNumber(): int;
function getPosition(): int;
function getValue(): int;
function getDataType(): TypeDescriptor;
function getAssociate(): _Interface;
function getGoAlwaysToNode(): SyntaxNode;
function getGoIfTrueToNode(): SyntaxNode;
function getGoIfFalseToNode(): SyntaxNode;
function getChildWithMaxLabelNumber(): SyntaxNode;
function getChildWithMinLabelNumber(): SyntaxNode;
property labelNumber: int read getLabelNumber;
property position: int read getPosition write setPosition;
property value: int read getValue write setValue;
property dataType: TypeDescriptor read getDataType write setDataType;
property associate: _Interface read getAssociate write setAssociate;
property goAlwaysToNode: SyntaxNode read getGoAlwaysToNode write setGoAlwaysToNode;
property goIfTrueToNode: SyntaxNode read getGoIfTrueToNode write setGoIfTrueToNode;
property goIfFalseToNode: SyntaxNode read getGoIfFalseToNode write setGoIfFalseToNode;
end;
SyntaxTree = interface(Tree) ['{2187DBA7-8D82-42DE-95E7-6B43015BBA94}']
procedure deleteLabelNumber(labelNumber: int);
function assignLabelNumberTo(node: SyntaxNode): int;
function setLabelNumber(node: SyntaxNode; labelNumber: int): int;
function getNodesWithLabelNumberCount(): int;
function getNodeWithLabelNumber(labelNumber: int): SyntaxNode;
function getLexemes(): Lexer;
property lexemes: Lexer read getLexemes;
end;
TranslatorSyntaxNode = class(RefCountInterfacedObject, Node, SyntaxNode)
public
constructor create(); virtual;
procedure setIndex(index: int); virtual;
procedure setParent(parent: Node; index: int); virtual;
function isParent(parentForTest: Node): boolean; virtual;
function getIndex(): int; virtual;
function getChildrensCount(): int; virtual;
function getChild(index: int): Node; virtual;
function getParent(): Node; virtual;
function getOwner(): Tree; virtual;
function enumerateChildrens(): NodeEnumerator; virtual;
procedure clearData(); virtual;
procedure setPosition(position: int); virtual;
procedure setValue(value: int); virtual;
procedure setAssociate(associate: _Interface); virtual;
procedure setDataType(dataType: TypeDescriptor); virtual;
procedure setDataAssociate(position, value: int;
dataType: TypeDescriptor; associate: _Interface); virtual;
procedure setGoAlwaysToNode(goAlwaysToNode: SyntaxNode); virtual;
procedure setGoIfTrueToNode(goIfTrueToNode: SyntaxNode); virtual;
procedure setGoIfFalseToNode(goIfFalseToNode: SyntaxNode); virtual;
procedure setDataGoToNode(ifTrue, ifFalse: SyntaxNode); virtual;
function getLabelNumber(): int; virtual;
function getPosition(): int; virtual;
function getValue(): int; virtual;
function getDataType(): TypeDescriptor; virtual;
function getAssociate(): _Interface; virtual;
function getGoAlwaysToNode(): SyntaxNode; virtual;
function getGoIfTrueToNode(): SyntaxNode; virtual;
function getGoIfFalseToNode(): SyntaxNode; virtual;
function getChildWithMaxLabelNumber(): SyntaxNode; virtual;
function getChildWithMinLabelNumber(): SyntaxNode; virtual;
private
labelNumber: int;
index: int;
count: int;
childrens: Node_Array1d;
parent: TranslatorSyntaxNode;
owner: TranslatorSyntaxTree;
procedure addChild(child: Node);
procedure insertChild(index: int; child: Node);
procedure deleteChild(index: int);
function isSubNodeFor(parentForTest: TranslatorSyntaxNode): boolean;
private
position: int;
value: int;
dataType: TypeDescriptor;
associate: _Interface;
goAlwaysToNode: SyntaxNode;
goIfTrueToNode: SyntaxNode;
goIfFalseToNode: SyntaxNode;
end;
TranslatorSyntaxTree = class(RefCountInterfacedObject, Tree, SyntaxTree)
public
constructor create(); overload;
constructor create(lexemes: Lexer); overload;
constructor create(lexemes: Lexer; nodesClass: TranslatorSyntaxNode_Class); overload;
procedure deleteChildrens(parent: Node); virtual;
procedure deleteNode(sibling: Node); virtual;
function addChildLast(parent: Node): Node; virtual;
function addChildFirst(parent: Node): Node; virtual;
function addNodeAfter(sibling: Node): Node; virtual;
function addNodeBefore(sibling: Node): Node; virtual;
function getRoot(): Node; virtual;
procedure deleteLabelNumber(labelNumber: int); virtual;
function assignLabelNumberTo(node: SyntaxNode): int; virtual;
function setLabelNumber(node: SyntaxNode; labelNumber: int): int; virtual;
function getNodesWithLabelNumberCount(): int; virtual;
function getNodeWithLabelNumber(labelNumber: int): SyntaxNode; virtual;
function getLexemes(): Lexer; virtual;
private
count: int;
countWithLabelNumber: int;
nodes: Node_Array1d;
root: SyntaxNode;
lexemes: Lexer;
nodesClass: TranslatorSyntaxNode_Class;
procedure add(node: Node);
procedure delete(index: int);
procedure move(oldIndex, newIndex: int);
function indexOf(node: Node): int;
end;
resourcestring
msgCannotChangeParentOnDeleted = 'Нельзя сменить родительский узел у удалённого узла.';
msgCannotChangeParentOnRootNode = 'Нельзя сменить родительский узел у корневого узла.';
msgCannotSetSubNodeAsParent = 'Нельзя установить подчинённый узел в качестве родительского.';
implementation
type
TranslatorNodeEnumerator = class;
TranslatorNodeEnumerator = class(RefCountInterfacedObject, NodeEnumerator)
public
constructor create(node: TranslatorSyntaxNode);
destructor destroy; override;
function nextChild(): Node; virtual;
function nextSibling(): Node; virtual;
strict private
index: int;
istack: Stack;
node: TranslatorSyntaxNode;
end;
function ifThen(condition: boolean; valueIfTrue, valueIfFalse: int): int; inline;
begin
if condition = true then begin
result := valueIfTrue;
end else begin
result := valueIfFalse;
end;
end;
{ TranslatorSyntaxNode }
constructor TranslatorSyntaxNode.create();
begin
inherited create();
end;
procedure TranslatorSyntaxNode.setIndex(index: int);
begin
setParent(parent, index);
end;
procedure TranslatorSyntaxNode.setParent(parent: Node; index: int);
var
oldIndex: int;
newIndex: int;
oldParent: TranslatorSyntaxNode;
newParent: TranslatorSyntaxNode;
ownedTree: TranslatorSyntaxTree;
begin
ownedTree := self.owner;
if ownedTree = nil then begin
raise IllegalStateException.create(msgCannotChangeParentOnDeleted);
end;
if parent = nil then begin
parent := ownedTree.root;
end;
if not (parent is TranslatorSyntaxNode) or
(ownedTree <> (parent as TranslatorSyntaxNode).owner) then begin
raise IllegalArgumentException.create(msgIllegalArgument + 'parent');
end;
oldParent := self.parent;
if oldParent = nil then begin
raise IllegalStateException.create(msgCannotChangeParentOnRootNode);
end;
newParent := parent as TranslatorSyntaxNode;
if (newParent = self) or newParent.isSubNodeFor(self) then begin
raise IllegalArgumentException.create(msgCannotSetSubNodeAsParent);
end;
oldIndex := self.index;
newIndex := Math.max(Math.min(newParent.count, index), 0);
if (newParent = oldParent) and (newIndex > oldIndex) then begin
dec(newIndex);
end;
oldParent.deleteChild(oldIndex);
newParent.insertChild(newIndex, self);
self.parent := newParent;
end;
function TranslatorSyntaxNode.isParent(parentForTest: Node): boolean;
var
current: TranslatorSyntaxNode;
parentAsObject: TObject;
begin
current := self;
parentAsObject := parentForTest as TObject;
while (current <> nil) and (current <> parentAsObject) do begin
current := current.parent;
end;
result := current = parentAsObject;
end;
function TranslatorSyntaxNode.getIndex(): int;
begin
result := index;
end;
function TranslatorSyntaxNode.getChildrensCount(): int;
begin
result := count;
end;
function TranslatorSyntaxNode.getChild(index: int): Node;
begin
if (index < 0) or (index >= count) then begin
raise IndexOutOfBoundsException.create(msgIndexOutOfBounds);
end;
result := childrens[index];
end;
function TranslatorSyntaxNode.getParent(): Node;
begin
result := parent;
end;
function TranslatorSyntaxNode.getOwner(): Tree;
begin
result := owner;
end;
function TranslatorSyntaxNode.enumerateChildrens(): NodeEnumerator;
begin
result := TranslatorNodeEnumerator.create(self);
end;
procedure TranslatorSyntaxNode.clearData();
begin
position := -1;
value := 0;
dataType := nil;
associate := nil;
goAlwaysToNode := nil;
goIfTrueToNode := nil;
goIfFalseToNode := nil;
end;
procedure TranslatorSyntaxNode.setPosition(position: int);
begin
self.position := position;
end;
procedure TranslatorSyntaxNode.setValue(value: int);
begin
self.value := value;
end;
procedure TranslatorSyntaxNode.setAssociate(associate: _Interface);
begin
self.associate := associate;
end;
procedure TranslatorSyntaxNode.setDataType(dataType: TypeDescriptor);
begin
self.dataType := dataType;
end;
procedure TranslatorSyntaxNode.setDataAssociate(position, value: int;
dataType: TypeDescriptor; associate: _Interface);
begin
self.position := position;
self.value := value;
self.dataType := dataType;
self.associate := associate;
end;
procedure TranslatorSyntaxNode.setGoAlwaysToNode(goAlwaysToNode: SyntaxNode);
begin
self.goAlwaysToNode := goAlwaysToNode;
self.goIfTrueToNode := nil;
self.goIfFalseToNode := nil;
end;
procedure TranslatorSyntaxNode.setGoIfTrueToNode(goIfTrueToNode: SyntaxNode);
begin
self.goAlwaysToNode := nil;
self.goIfTrueToNode := goIfTrueToNode;
end;
procedure TranslatorSyntaxNode.setGoIfFalseToNode(goIfFalseToNode: SyntaxNode);
begin
self.goAlwaysToNode := nil;
self.goIfFalseToNode := goIfFalseToNode;
end;
procedure TranslatorSyntaxNode.setDataGoToNode(ifTrue, ifFalse: SyntaxNode);
begin
self.goAlwaysToNode := nil;
self.goIfTrueToNode := ifTrue;
self.goIfFalseToNode := ifFalse;
end;
function TranslatorSyntaxNode.getLabelNumber(): int;
begin
result := labelNumber;
end;
function TranslatorSyntaxNode.getPosition(): int;
begin
result := position;
end;
function TranslatorSyntaxNode.getValue(): int;
begin
result := value;
end;
function TranslatorSyntaxNode.getDataType(): TypeDescriptor;
begin
result := dataType;
end;
function TranslatorSyntaxNode.getAssociate(): _Interface;
begin
result := associate;
end;
function TranslatorSyntaxNode.getGoAlwaysToNode(): SyntaxNode;
begin
result := goAlwaysToNode;
end;
function TranslatorSyntaxNode.getGoIfTrueToNode(): SyntaxNode;
begin
result := goIfTrueToNode;
end;
function TranslatorSyntaxNode.getGoIfFalseToNode(): SyntaxNode;
begin
result := goIfFalseToNode;
end;
function TranslatorSyntaxNode.getChildWithMaxLabelNumber(): SyntaxNode;
var
nodeLabelNumber: int;
resultLabelNumber: int;
node: TranslatorSyntaxNode;
enum: NodeEnumerator;
begin
resultLabelNumber := self.labelNumber;
if resultLabelNumber < 0 then begin
result := nil;
end else begin
result := self;
end;
enum := TranslatorNodeEnumerator.create(self);
repeat
node := enum.nextChild() as TranslatorSyntaxNode;
if node = nil then begin
break;
end;
nodeLabelNumber := node.labelNumber;
if (nodeLabelNumber >= 0) and ((resultLabelNumber < 0) or
(nodeLabelNumber > resultLabelNumber)) then begin
resultLabelNumber := nodeLabelNumber;
result := node;
end;
until false;
end;
function TranslatorSyntaxNode.getChildWithMinLabelNumber(): SyntaxNode;
var
nodeLabelNumber: int;
resultLabelNumber: int;
node: TranslatorSyntaxNode;
enum: NodeEnumerator;
begin
resultLabelNumber := self.labelNumber;
if resultLabelNumber < 0 then begin
result := nil;
end else begin
result := self;
end;
enum := TranslatorNodeEnumerator.create(self);
repeat
node := enum.nextChild() as TranslatorSyntaxNode;
if node = nil then begin
break;
end;
nodeLabelNumber := node.labelNumber;
if (nodeLabelNumber >= 0) and ((resultLabelNumber < 0) or
(nodeLabelNumber < resultLabelNumber)) then begin
resultLabelNumber := nodeLabelNumber;
result := node;
end;
until false;
end;
procedure TranslatorSyntaxNode.addChild(child: Node);
var
c: int;
childrens: Node_Array1d;
newchildrens: Node_Array1d;
begin
c := self.count;
childrens := self.childrens;
if length(childrens) = c then begin
newchildrens := Node_Array1d(Interface_Array1d_create((c shl 1) + 1));
arraycopyInterfaces(childrens, 0, newchildrens, 0, c);
self.childrens := newchildrens;
childrens := newchildrens;
end;
childrens[c] := child;
self.count := c + 1;
end;
procedure TranslatorSyntaxNode.insertChild(index: int; child: Node);
var
i: int;
c: int;
e: int;
childrens: Node_Array1d;
newchildrens: Node_Array1d;
begin
c := self.count;
childrens := self.childrens;
if length(childrens) = c then begin
newchildrens := Node_Array1d(Interface_Array1d_create((c shl 1) + 1));
arraycopyInterfaces(childrens, 0, newchildrens, 0, c);
self.childrens := newchildrens;
childrens := newchildrens;
end;
e := c - index;
if e > 0 then begin
arraycopyInterfaces(childrens, index, childrens, index + 1, e);
end;
childrens[index] := child;
self.count := c + 1;
for i := index to c do begin
(childrens[i] as TranslatorSyntaxNode).index := i;
end;
end;
procedure TranslatorSyntaxNode.deleteChild(index: int);
var
i: int;
c: int;
e: int;
childrens: Node_Array1d;
begin
c := self.count - 1;
e := c - index;
childrens := self.childrens;
if e > 0 then begin
arraycopyInterfaces(childrens, index + 1, childrens, index, e);
end;
childrens[c] := nil;
self.count := c;
for i := c - 1 downto index do begin
(childrens[i] as TranslatorSyntaxNode).index := i;
end;
end;
function TranslatorSyntaxNode.isSubNodeFor(parentForTest: TranslatorSyntaxNode): boolean;
var
current: TranslatorSyntaxNode;
begin
current := self.parent;
while (current <> nil) and (current <> parentForTest) do begin
current := current.parent;
end;
result := current = parentForTest;
end;
{ TranslatorSyntaxTree }
constructor TranslatorSyntaxTree.create();
begin
create(nil, TranslatorSyntaxNode);
end;
constructor TranslatorSyntaxTree.create(lexemes: Lexer);
begin
create(lexemes, TranslatorSyntaxNode);
end;
constructor TranslatorSyntaxTree.create(lexemes: Lexer; nodesClass: TranslatorSyntaxNode_Class);
var
root: TranslatorSyntaxNode;
begin
inherited create();
if nodesClass = nil then begin
nodesClass := TranslatorSyntaxNode;
end;
root := nodesClass.create();
root.labelNumber := -1;
root.index := -1;
root.owner := self;
root.position := -1;
self.count := 1;
self.countWithLabelNumber := 0;
self.nodes := Node_Array1d(Interface_Array1d_create([
root as SyntaxNode
]));
self.root := root;
self.lexemes := lexemes;
self.nodesClass := nodesClass;
end;
procedure TranslatorSyntaxTree.deleteChildrens(parent: Node);
var
i: int;
c: int;
nodes: Node_Array1d;
current: TranslatorSyntaxNode;
parentAsSyntaxNode: TranslatorSyntaxNode;
begin
if parent = nil then begin
parent := root;
end;
if not (parent is TranslatorSyntaxNode) or
(self <> (parent as TranslatorSyntaxNode).owner) then begin
raise IllegalArgumentException.create(msgIllegalArgument + 'parent');
end;
c := self.count - 1;
nodes := self.nodes;
parentAsSyntaxNode := parent as TranslatorSyntaxNode;
for i := c downto 0 do begin
current := nodes[i] as TranslatorSyntaxNode;
if current.isSubNodeFor(parentAsSyntaxNode) then begin
current.owner := nil;
end;
end;
for i := c downto 0 do begin
current := nodes[i] as TranslatorSyntaxNode;
if current.owner <> nil then begin
continue;
end;
if current.parent = parentAsSyntaxNode then begin
current.index := -1;
current.parent := nil;
end;
current.clearData();
delete(i);
end;
parentAsSyntaxNode.count := 0;
parentAsSyntaxNode.childrens := nil;
end;
procedure TranslatorSyntaxTree.deleteNode(sibling: Node);
var
i: int;
c: int;
index: int;
nodes: Node_Array1d;
current: TranslatorSyntaxNode;
parentAsSyntaxNode: TranslatorSyntaxNode;
siblingAsSyntaxNode: TranslatorSyntaxNode;
begin
if not (sibling is TranslatorSyntaxNode) or
(self <> (sibling as TranslatorSyntaxNode).owner) or (root = sibling) then begin
raise IllegalArgumentException.create(msgIllegalArgument + 'sibling');
end;
c := self.count - 1;
nodes := self.nodes;
siblingAsSyntaxNode := sibling as TranslatorSyntaxNode;
parentAsSyntaxNode := siblingAsSyntaxNode.parent;
index := siblingAsSyntaxNode.index;
for i := c downto 0 do begin
current := nodes[i] as TranslatorSyntaxNode;
if (current = siblingAsSyntaxNode) or current.isSubNodeFor(siblingAsSyntaxNode) then begin
current.owner := nil;
end;
end;
for i := c downto 0 do begin
current := nodes[i] as TranslatorSyntaxNode;
if current.owner <> nil then begin
continue;
end;
if current = siblingAsSyntaxNode then begin
current.index := -1;
current.parent := nil;
end;
current.clearData();
delete(i);
end;
parentAsSyntaxNode.deleteChild(index);
end;
function TranslatorSyntaxTree.addChildLast(parent: Node): Node;
var
resultAsSyntaxNode: TranslatorSyntaxNode;
parentAsSyntaxNode: TranslatorSyntaxNode;
begin
if parent = nil then begin
parent := root;
end;
if not (parent is TranslatorSyntaxNode) or
(self <> (parent as TranslatorSyntaxNode).owner) then begin
raise IllegalArgumentException.create(msgIllegalArgument + 'parent');
end;
parentAsSyntaxNode := parent as TranslatorSyntaxNode;
resultAsSyntaxNode := nodesClass.create();
resultAsSyntaxNode.labelNumber := -1;
resultAsSyntaxNode.index := parentAsSyntaxNode.count;
resultAsSyntaxNode.parent := parentAsSyntaxNode;
resultAsSyntaxNode.owner := self;
resultAsSyntaxNode.position := -1;
result := resultAsSyntaxNode;
parentAsSyntaxNode.addChild(result);
add(result);
end;
function TranslatorSyntaxTree.addChildFirst(parent: Node): Node;
var
resultAsSyntaxNode: TranslatorSyntaxNode;
parentAsSyntaxNode: TranslatorSyntaxNode;
begin
if parent = nil then begin
parent := root;
end;
if not (parent is TranslatorSyntaxNode) or
(self <> (parent as TranslatorSyntaxNode).owner) then begin
raise IllegalArgumentException.create(msgIllegalArgument + 'parent');
end;
parentAsSyntaxNode := parent as TranslatorSyntaxNode;
resultAsSyntaxNode := nodesClass.create();
resultAsSyntaxNode.labelNumber := -1;
resultAsSyntaxNode.index := 0;
resultAsSyntaxNode.parent := parentAsSyntaxNode;
resultAsSyntaxNode.owner := self;
resultAsSyntaxNode.position := -1;
result := resultAsSyntaxNode;
parentAsSyntaxNode.insertChild(0, result);
add(result);
end;
function TranslatorSyntaxTree.addNodeAfter(sibling: Node): Node;
var
index: int;
resultAsSyntaxNode: TranslatorSyntaxNode;
parentAsSyntaxNode: TranslatorSyntaxNode;
siblingAsSyntaxNode: TranslatorSyntaxNode;
begin
if not (sibling is TranslatorSyntaxNode) or
(self <> (sibling as TranslatorSyntaxNode).owner) or (root = sibling) then begin
raise IllegalArgumentException.create(msgIllegalArgument + 'sibling');
end;
siblingAsSyntaxNode := sibling as TranslatorSyntaxNode;
parentAsSyntaxNode := siblingAsSyntaxNode.parent;
resultAsSyntaxNode := nodesClass.create();
index := siblingAsSyntaxNode.index + 1;
resultAsSyntaxNode.labelNumber := -1;
resultAsSyntaxNode.index := index;
resultAsSyntaxNode.parent := parentAsSyntaxNode;
resultAsSyntaxNode.owner := self;
resultAsSyntaxNode.position := -1;
result := resultAsSyntaxNode;
parentAsSyntaxNode.insertChild(index, result);
add(result);
end;
function TranslatorSyntaxTree.addNodeBefore(sibling: Node): Node;
var
index: int;
resultAsSyntaxNode: TranslatorSyntaxNode;
parentAsSyntaxNode: TranslatorSyntaxNode;
siblingAsSyntaxNode: TranslatorSyntaxNode;
begin
if not (sibling is TranslatorSyntaxNode) or
(self <> (sibling as TranslatorSyntaxNode).owner) or (root = sibling) then begin
raise IllegalArgumentException.create(msgIllegalArgument + 'sibling');
end;
siblingAsSyntaxNode := sibling as TranslatorSyntaxNode;
parentAsSyntaxNode := siblingAsSyntaxNode.parent;
resultAsSyntaxNode := nodesClass.create();
index := siblingAsSyntaxNode.index;
resultAsSyntaxNode.labelNumber := -1;
resultAsSyntaxNode.index := index;
resultAsSyntaxNode.parent := parentAsSyntaxNode;
resultAsSyntaxNode.owner := self;
resultAsSyntaxNode.position := -1;
result := resultAsSyntaxNode;
parentAsSyntaxNode.insertChild(index, result);
add(result);
end;
function TranslatorSyntaxTree.getRoot(): Node;
begin
result := root;
end;
procedure TranslatorSyntaxTree.deleteLabelNumber(labelNumber: int);
var
w: int;
begin
w := countWithLabelNumber - 1;
if (labelNumber < 0) or (labelNumber > w) then begin
raise IndexOutOfBoundsException.create(msgIndexOutOfBounds);
end;
countWithLabelNumber := w;
move(labelNumber, w);
end;
function TranslatorSyntaxTree.assignLabelNumberTo(node: SyntaxNode): int;
var
nodeAsSyntaxNode: TranslatorSyntaxNode;
begin
if node = nil then begin
raise NullPointerException.create(msgNullPointer);
end;
if not (node is TranslatorSyntaxNode) or
(self <> (node as TranslatorSyntaxNode).owner) then begin
raise IllegalArgumentException.create(msgIllegalArgument + 'node');
end;
nodeAsSyntaxNode := node as TranslatorSyntaxNode;
result := nodeAsSyntaxNode.labelNumber;
if result >= 0 then begin
exit;
end;
result := countWithLabelNumber;
countWithLabelNumber := result + 1;
move(indexOf(node), result);
end;
function TranslatorSyntaxTree.setLabelNumber(node: SyntaxNode; labelNumber: int): int;
var
w: int;
currentNumber: int;
nodeAsSyntaxNode: TranslatorSyntaxNode;
begin
if node = nil then begin
raise NullPointerException.create(msgNullPointer);
end;
if not (node is TranslatorSyntaxNode) or
(self <> (node as TranslatorSyntaxNode).owner) then begin
raise IllegalArgumentException.create(msgIllegalArgument + 'node');
end;
nodeAsSyntaxNode := node as TranslatorSyntaxNode;
currentNumber := nodeAsSyntaxNode.labelNumber;
w := countWithLabelNumber;
if labelNumber < -1 then begin
labelNumber := -1;
end;
if currentNumber >= 0 then begin
if labelNumber >= 0 then begin
if labelNumber >= w then begin
labelNumber := w - 1;
end;
move(currentNumber, labelNumber);
end else begin
dec(w);
countWithLabelNumber := w;
move(currentNumber, w);
end;
end else
if labelNumber >= 0 then begin
if labelNumber > w then begin
labelNumber := w;
end;
countWithLabelNumber := w + 1;
move(indexOf(node), labelNumber);
end;
result := labelNumber;
end;
function TranslatorSyntaxTree.getNodesWithLabelNumberCount(): int;
begin
result := countWithLabelNumber;
end;
function TranslatorSyntaxTree.getNodeWithLabelNumber(labelNumber: int): SyntaxNode;
begin
if (labelNumber < 0) or (labelNumber >= countWithLabelNumber) then begin
raise IndexOutOfBoundsException.create(msgIndexOutOfBounds);
end;
result := nodes[labelNumber] as SyntaxNode;
end;
function TranslatorSyntaxTree.getLexemes(): Lexer;
begin
result := lexemes;
end;
procedure TranslatorSyntaxTree.add(node: Node);
var
c: int;
nodes: Node_Array1d;
newnodes: Node_Array1d;
begin
c := self.count;
nodes := self.nodes;
if length(nodes) = c then begin
newnodes := Node_Array1d(Interface_Array1d_create((c shl 1) + 1));
arraycopyInterfaces(nodes, 0, newnodes, 0, c);
self.nodes := newnodes;
nodes := newnodes;
end;
nodes[c] := node;
self.count := c + 1;
end;
procedure TranslatorSyntaxTree.delete(index: int);
var
i: int;
c: int;
w: int;
e: int;
nodes: Node_Array1d;
begin
c := self.count - 1;
w := self.countWithLabelNumber - 1;
e := c - index;
nodes := self.nodes;
if e > 0 then begin
arraycopyInterfaces(nodes, index + 1, nodes, index, e);
end;
if index <= w then begin
self.countWithLabelNumber := w;
for i := w downto index do begin
(nodes[i] as TranslatorSyntaxNode).labelNumber := ifThen(i < w, i, -1);
end;
end;
nodes[c] := nil;
self.count := c;
end;
procedure TranslatorSyntaxTree.move(oldIndex, newIndex: int);
var
i: int;
w: int;
nodes: Node_Array1d;
n: Node;
begin
w := self.countWithLabelNumber;
nodes := self.nodes;
n := nodes[oldIndex];
if oldIndex < newIndex then begin
{ перемещение вперёд }
arraycopyInterfaces(nodes, oldIndex + 1, nodes, oldIndex, newIndex - oldIndex);
nodes[newIndex] := n;
for i := oldIndex to newIndex do begin
(nodes[i] as TranslatorSyntaxNode).labelNumber := ifThen(i < w, i, -1);
end;
end else
if newIndex < oldIndex then begin
{ перемещение назад }
arraycopyInterfaces(nodes, newIndex, nodes, newIndex + 1, oldIndex - newIndex);
nodes[newIndex] := n;
for i := newIndex to oldIndex do begin
(nodes[i] as TranslatorSyntaxNode).labelNumber := ifThen(i < w, i, -1);
end;
end else begin
{ остаться на месте }
i := oldIndex;
(nodes[i] as TranslatorSyntaxNode).labelNumber := ifThen(i < w, i, -1);
end;
end;
function TranslatorSyntaxTree.indexOf(node: Node): int;
var
i: int;
nodes: Node_Array1d;
nobj: TObject;
begin
nodes := self.nodes;
nobj := node as TObject;
for i := count - 1 downto 0 do begin
if (nodes[i] as TObject) = nobj then begin
result := i;
exit;
end;
end;
result := -1;
end;
{ TranslatorNodeEnumerator }
constructor TranslatorNodeEnumerator.create(node: TranslatorSyntaxNode);
begin
inherited create();
self.index := 0;
self.istack := Stack.create();
self.node := node;
end;
destructor TranslatorNodeEnumerator.destroy;
begin
istack.free();
inherited destroy;
end;
function TranslatorNodeEnumerator.nextChild(): Node;
var
index: int;
istack: Stack;
node: TranslatorSyntaxNode;
resultAsSyntaxNode: TranslatorSyntaxNode;
begin
istack := self.istack;
index := self.index;
node := self.node;
try
repeat
if index < node.count then begin
result := node.childrens[index];
resultAsSyntaxNode := result as TranslatorSyntaxNode;
inc(index);
if resultAsSyntaxNode.count > 0 then begin
istack.push(index);
index := 0;
node := resultAsSyntaxNode;
end;
break;
end else
if istack.isEmpty() then begin
result := nil;
break;
end else begin
index := (istack.pop() as IntegerAsObject).intValue();
node := node.parent;
end;
until false;
finally
self.index := index;
self.node := node;
end;
end;
function TranslatorNodeEnumerator.nextSibling(): Node;
var
index: int;
istack: Stack;
node: TranslatorSyntaxNode;
begin
istack := self.istack;
index := self.index;
node := self.node;
try
repeat
if index < node.count then begin
result := node.childrens[index];
inc(index);
break;
end else
if istack.isEmpty() then begin
result := nil;
break;
end else begin
index := (istack.pop() as IntegerAsObject).intValue();
node := node.parent;
end;
until false;
finally
self.index := index;
self.node := node;
end;
end;
end.