[ Team LiB ]
Chapter 5. Advanced Control Flow
It is necessary for technical reasons that these warheads be stored upside down, that is, with the top at the bottom 
and the bottom at the top. In order that there may be no doubt as to which is the bottom and which is the top, it will 
be seen to it that the bottom of each warhead immediately be labeled with the word TOP.
—British Admiralty Regulatio n
In Chapter 2
we examined a number of statements that influence the control flow of a program's instruction sequence. Although the 
control statements we described suffice for most common programming tasks and are the ones you will most often encounter, some less 
common elements are nevertheless important for a number of applications. Recursive code often mirrors data structures or algorithms 
with a similar definition. Exceptions are used in C++ and Java to streamline error handling. By using software or hardwareparallelism , 
programs can enhance responsiveness, structure work allocation, or effectively use computers with multiple processors. When 
parallelism facilities are not available, programs may have to resort to the use of asynchronous signals (signals that can be delivered at 
any arbitrary point of time) and nonlocal jumps to respond to external events. Finally, in the name of efficiency, programmers sometimes 
use the macro substitution facilities of the C preprocessor in the place of the usual C function call mechanism.
[ Team LiB ]
Pdf image extractor - Select, copy, paste PDF images in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support PDF Image Extraction from a Page, a Region on a Page, and PDF Document
extract images pdf acrobat; some pdf image extract
Pdf image extractor - VB.NET PDF Image Extract Library: Select, copy, paste PDF images in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support PDF Image Extraction from a Page, a Region on a Page, and PDF Document
extract image from pdf in; extract pdf images
[ Team LiB ]
5.1 Recursion
A number of data structures such as trees and the heap, operations such as type inference and unification, mathematical entities such as 
the Fibonacci numbers and fractal graphs, and algorithms such as quicksort, tree traversals, and recursive descent parsing are defined 
recursively. A recursive definition of an entity or an operation defines its object in terms of itself. Such definitions are not infinitely circular, 
as they may initially appear, because a base case definition typically defines a special case that does not depend on a recursive 
definition. As an example, although the factorial of an integer n, n!, can be defined as n(n - 1), we also define a base case as 0! = 1.
Recursively defined algorithms and data structures are often implemented by using recursive function definitions. Although recursive 
function calls are just a special case of the function call we examined in Section 2.2
, the way they are coded and the way they should be 
read are sufficiently different to merit special treatment.
Consider the task of parsing shell commands. The command structure supported by the Unix Bourne 
shell is quite sophisticated. A representative part of the shell command grammar is outlined in Figure 5.1
a command type appearing before a colon is defined by one of the rules following in the indented lines. 
Notice how many commands are in more than one way recursively defined: a pipeline can be a 
command, or a pipeline followed by the pipe symbol (|), followed by a command; or a command can be a 
parentheses-enclosed command-list, which can be an andor, which can be a pipeline, which can again be 
command. Given such a grammar we typically want to recognize commands, store them in a suitable 
data structure, and process the data structure. Recursion is a key tool for all these tasks.
VB.NET TIFF: TIFF Text Extractor SDK; Extract Text Content from
Standalone VB.NET TIFF text extractor SDK that extracts text information from all TIFF this TIFF text extraction control SDK into VB.NET image application by
extract photos pdf; pdf image text extractor
VB.NET PowerPoint: Extract & Collect PPT Slide(s) Using VB Sample
demo code using RasterEdge VB.NET PowerPoint extractor library toolkit. provide powerful & profession imaging controls, PDF document, image to pdf files and
extract pictures pdf; how to extract images from pdf
Figure 5.1. Bourne shell command grammar.
simple-command:
item
simple-command item
command:
simple-command
(command-list)
{ command-list }
for name do command-list done
for name in word ... do command-list done
while command-list do command-list done
until command-list do command-list done
case word in case-part ... esac
if command-list then command-list else else-part fi
pipeline:
command
pipeline | command
andor:
pipeline
andor && pipeline
andor || pipeline
command-list:
andor
command-list ;
command-list &
command-list ; andor
command-list & andor
Individual shell commands are stored internally as a tree. Since various command types can alternatively 
consist of different elements, all tree nodes are represented by using a union of all possible 
VB.NET Word: Extract Word Pages, DOCX Page Extraction SDK
this VB.NET Word page extractor add-on can be also used to merge / split Word file, add / delete Word page, sort Word page order or insert image into Word page
extract image from pdf c#; extract jpg from pdf
VB.NET TIFF: TIFF to Text (TXT) Converter SDK; Convert TIFF to
NET developers to interpret and decode TIFF image file. But different from TIFF text extractor add-on powerful & profession imaging controls, PDF document, tiff
extract photo from pdf; how to extract a picture from a pdf
elements.
[1]
,[2]
[1]
netbsdsrc/bin/sh/nodetypes; used as an input file to automatically generate 
node definitions.
[2]
Notice how the same name is being used both as a structure tag and as a union 
member.
union node {
int type;
struct nbinary nbinary;
struct ncmd ncmd;
struct npipe npipe;
struct nif nif;
struct nfor nfor;
struct ncase ncase;
struct nclist nclist;
[...]
};
Each element type is recursively defined as a structure containing pointers to command tree nodes appropriate for the given type.
struct nif {
int type;
union node *test;
union node *ifpart;
union node *elsepart;
};
Note that in the above code the union and the corresponding struct share the common int type element. In 
this way the individual structures can access the union's type field by using the corresponding struct's 
field with the same name. This is not a particularly good programming practice since the layout 
correspondence between the fields of the struct and the union is manually maintained by the programmer 
and never verified by the compiler or the runtime system. Should one of the layouts change, the program 
will still compile and run but may fail in unpredictable ways. In addition, according to our interpretation of 
the C standard, the correlation between the two layouts is guaranteed to hold only for dereferencing via a 
pointer the first element of a structure.
Figure 5.2 Recursively printing the parsed command tree.
STATIC void
cmdtxt(union node *n)
{
union node *np;
struct nodelist *lp;
if (n == NULL)
return;
switch (n->type) {
case NSEMI:
cmdtxt(n->nbinary.ch1);
cmdputs("; ");
C# Word: How to Extract Text from C# Word in .NET Project
you can rest assured because this Word text extractor preserves both to provide powerful & profession imaging controls, PDF document, image to pdf files and
how to extract pictures from pdf files; extract jpeg from pdf
cmdtxt(n->nbinary.ch2);
break;
case NAND:
cmdtxt(n->nbinary.ch1);
cmdputs(" && ");
cmdtxt(n->nbinary.ch2);
break;
/* ... */
case NPIPE:
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
cmdtxt(lp->n);
if (lp->next)
cmdputs(" | ");
}
break;
/* ... */
}
}
Base case: empty command; return
command1 ; command2
Recursively print first command
Recursively print second command
command1 && command2
Command pipeline
Recursively print each command
Figure 5.2
[3]
is the code used to print the Unix shell command(s) executing in the background as a response to the shejobsll  built-in 
command. The cmdtxt function has as its only argument a pointer to the command tree that is to be displayed. The first test inside the 
cmdtxt function (Figure 5.2:1
) is crucial: it ensures that commands represented by a NULL pointer (for example, an empty else part in an if
command) are correctly handled. Notice that the handling of empty commands does not involve recursion; the cmdtxt function simply 
returns. Since commands are represented as a tree and all the trees leaves (terminal nodes) are NULL, recursive descends of tree 
branches will eventually reach a leaf and terminate. This base case test and its nonrecursive definition guarantees that the recursive 
function will eventually terminate. Informal arguments such as the above are an important tool for understanding code involving 
recursion. Once we understand how a function defined in terms of itself can work, the rest of its code falls easily into place. A case for 
each different nonempty command (tree node) type (Figure 5.2:4
) prints the command based on its constituent parts. As an example, a 
semicolon-separated command list is displayed by printing the first command of the list (Figure 5.2:2
), a semicolon, and the second 
command (Figure 5.2:3
).
[3]
netbsdsrc/bin/sh/jobs.c:959–108 2
The recursive grammar definition we saw in Figure 5.1
also lends itself for parsing by using a series of functions that follow the
grammar's structure—a  recursive descent parser. This approach is often used when parsing relatively simple structures such as 
command- or domain-specific languages, expressions, or text-based data files. Figure 5.3
[4]
contains representative elements of the 
code used for parsing shell commands. Notice the symmetry between the parsing code and the grammar; it extends even to the naming 
of identifiers, although the specific parser was written by Kenneth Almquist at least ten years after Stephen Bourne implemented the 
original shell and documented its grammar. The structure of the recursive descent parser is remarkably simple. Each function is 
responsible for parsing a specific grammar element (a command list, an andor command, a pipeline, or a simple command) and for 
returning a node consisting of that element. All functions work by calling other functions to parse the grammar elements that make up the 
given command and the readtoken() function to read plain tokens such as if and while.
[4]
netbsdsrc/bin/sh/jobs.c:157–51 3
The functions that print command nodes and parse commands are not strictly recursive since no statement in the function body directly 
calls the function that contains it. However, the functions call other functions, which call other functions, which may call the original 
functions. This type of recursion is called mutual recursion. Although code based on it may appear more difficult to understand than 
simple recursive functions, one can easily reason about it by considering the recursive definition of the underlying concept.
When all recursive calls to a function occur exactly before the function's return points, we say that the 
function is tail recursive. Tail recursion is an important concept because the compiler can optimize these 
calls into simple jumps, thus saving the function call time and memory overhead. Tail-recursive calls are 
equivalent to a loop going back to the beginning of the function. You will sometimes see tail-recursive 
calls used instead of conventional loops, a goto, or a continue statement. The code in Figure 5.4
[5]
is a 
representative example. The object is to locate a server (termed driver in the source code) for the 
multiuser game hunt. If no server is found, the code attempts to launch a new server, waits for the server 
to register, and performs the server location procedure again using a tail-recursive call.
[5]
netbsdsrc/games/hunt/hunt/hunt.c:553–61 9
Figure 5.3 Recursive descent parser for shell commands.
<-- a
STATIC union node *
list(int nlflag) {
union node *n1, *n2, *n3;
if (nlflag == 0 && tokendlist[peektoken()])
return NULL;
n1 = NULL;
for (;;) {
n2 = andor();
<-- b
[...]
<-- c
STATIC union node *
andor() {
union node *n1, *n2, *n3;
int t;
n1 = pipeline();
for (;;) {
if ((t = readtoken()) == TAND) {
t = NAND;
}else if (t == TOR) {
t = NOR;
}else {
tokpushback++;
return n1;
}
n2 = pipeline();
[....]
<-- c
STATIC union node *
pipeline() {
union node *n1, *pipenode;
struct nodelist *lp, *prev;
n1 = command();
if (readtoken() == TPIPE) {
pipenode = (union node *)stalloc(sizeof (struct npipe));
pipenode->type = NPIPE;
lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
pipenode->npipe.cmdlist = lp;
lp->n = n1;
do {
<-- d
prev = lp;
lp = (struct nodelist *)stalloc(sizeof (struct nodelist));
lp->n = command();
prev->next = lp;
} while (readtoken() == TPIPE);
lp->next = NULL;
n1 = pipenode;
}
return n1;
}
<-- e
STATIC union node *
command() {
switch (readtoken()) {
case TIF:
<-- f
n1 = (union node *)stalloc(sizeof (struct nif));
n1->type = NIF;
n1->nif.test = list(0);
if (readtoken() != TTHEN)
<-- g
synexpect(TTHEN);
n1->nif.ifpart = list(0);
n2 = n1; [...]
if (lasttoken == TELSE)
n2->nif.elsepart = list(0);
else {
n2->nif.elsepart = NULL;
tokpushback++;
}
[....]
(a) Parse a command list
(b) A list consists of andor commands
(c) Parse an andor command
An andor consists of pipelines
(c) Parse a pipeline
A pipeline consists of commands
(d) Link commands into a List
(e) Parse a command
(f) Parse if commands
Each command part is a list
(g) Expect then token; otherwise report syntax error
Figure 5.4 Tail recursion used instead of a loop.
void
find_driver(FLAG do_startup)
{
SOCKET    *hosts;
hosts = list_drivers();    
<-- a
if (hosts[0].sin_port != htons(0)) {
int    i, c;
<-- b
if (hosts[1].sin_port == htons(0)) {
Daemon = hosts[0];
return;
}
/* go thru list and return host that matches daemon */
<-- c
[...]
Daemon = hosts[c];
clear_the_screen();
return;
}
if (!do_startup)    
<-- d
return;
<-- e
start_driver();
sleep(2);
find_driver(FALSE);
}
(a) Locate a driver
(b) Exactly one driver found; use it and return
(c) More than one driver found; have the user select the driver and return
(d) Startup already tried; fail
(e) Attempt to start-up a new driver and retry
Exercise 5.1 The informal argument we used to reason about the termination of the cmdtxt function is just that: an informal argument. 
Provide an example of a data structure that could cause cmdtxt to enter an infinite recursive loop. What additional guarantees are 
needed to prevent this from happening?
Exercise 5.2 Based on the example provided in Section 10.5
, construct a simple tool to locate recursive function definitions. Run it on the 
provided source code and reason about the workings of three different recursive functions.
Exercise 5.3 Construct the grammar accepted by the expr command based on the recursive descent parser it uses to evaluate 
expressions.
[6]
[6]
netbsdsrc/bin/expr/expr.c:240–52 5
Exercise 5.4 Examine whether your compiler optimizes tail recursion by inspecting the generated symbolic code for a trivial tail-recursive
example. Do not forget to specify through a compiler switch the highest level of optimization.
Figure 5.5 Exception handling in Java.
public void remove(String id) 
throws IOException {
Connection _conn = getConnection();
String removeSql = "DELETE FROM "+sessionTable+" WHERE "+
sessionIdCol+" = ?"; [...]
try {
if(preparedRemoveSql == null)
[...]
preparedRemoveSql.setString(1, id);
preparedRemoveSql.execute();
} catch
(SQLException e
) {      
<-- a
log(sm.getString(getStoreName()+".SQLException", e));
} finally {
release(_conn);
_conn = null;
}
if (debug > 0)     
<-- b
log([...]);
}
Documents you may be interested
Documents you may be interested