ETSI
CONSTRUCT-SUCCESSORS (statementType *predecessor, graphType GI) {
// - statementType refers to the type of a node of the tree that is constructed
// - *predecessor refers to the last node that has been created
// - graphType denotes type of the graph of TTCN-3 statements
// - GI is called by value and refers to the subgraph consisting of all remaining TTCN-3
// statements that have to be taken into consideration
var graphType myGraph;
var statementType i, myStmt;
var statementType *newStmt, *firstInBranch; // pointers for new statement nodes in the
// tree that is constructed recursively
// Retrieving sets of TTCN-3 statements that have no predecessors in 'GI'
var statementSet enabStmts := ENABLED
(GI); // all statements without predecessor
var statementSet enabRecStmts := RECEIVING
(enabStmts); // receiving statements in 'enabStmts'
var statementSet enabNonRecStmts := enabStmts\enabRecStmts;
// non receiving statements in 'enabStmts'
if (GI.St == ∅) { // We assume that GI.St refers to the set of statements in GI
return; // No statements are left, termination criterion of Recursion
}
elseif (enabNonRecStmts != ∅) { // Handling of non receiving statements in 'enabStmts'
myStmt := RANDOM
(enabNonRecStmts);
// There can only be one statement in 'enabNonRec', because the Algorithm
// continues the construction until there is a branch that contributes to
// the interlave statement.
newStmt := create(myStmt, predecessor);
// Creation of a new tree node representing 'myStmt' in the tree
// and update of pointers in 'newStmt' and 'predecessor'.
if (KIND
(myStmt) == IF || KIND(myStmt) == BLOCKING_CALL) {
for each i in SUCCESSORS
(myStmt, GI) {
firstInBranch := create(i, newStmt);
// Creation of a second node for the first statement of in a branch due to
// an if-else statement.
// Note, this create statement will be used to create tree nodes
// representing the receiving statements in blocking call operations.
myGraph := DISCARD
({i, myStmt} ∪ REACHABLE(myStmt, GI)\REACHABLE(i, GI))
// Removal of i, myStmt and all statements that are reachable from
// myStmt but not reachable from i. The latter considers the branching of
// a flow of control in a subgraph of GI.
CONSTRUCT-SUCCESSORS(firstInBranch, myGraph); // NEXT RECURSION STEP
}
}
elseif (KIND
(myStmt) == ALT) {
for each (i in SUCCESSORS
(myStmt, GI) {
CONSTRUCT-SUCCESSORS(mystmt, DISCARD
(REACHABLE(myStmt, GI)\REACHABLE(i, GI)));
// NEXT RECURSION STEP, the DISCARD
(REACHABLE(myStmt, GI)\REACHABLE(i, GI))
// argument considers the branching of a flow of control due to different
// receiving events.
}
}
else { // mystmt is a stand-alone statement
CONSTRUCT-SUCCESSORS(newSonNode, DISCARD
(myStmt, GI));
// NEXT RECURSION STEP
}
}
else { // Handling of receiving events that interleave
if (KIND
(predecessor) != ALT) { // an alt node is missing and has to be created, if the
// interleaving is not influenced by an embedded alt statement
predecessor := create(ALT, predecessor);
}
for each i in enabRecStmts) {
newStmt := create(i, predecessor); // New tree node
CONSTRUCT-SUCCESSORS(newStmt, DISCARD
(i, GI)); // NEXT RECURSION STEP(S)
}
}
}
Figure 7: Replacement algorithm for TTCN-3 interleave statements