Immediate download Programming Languages Principles and Practices 3rd Edition Louden Solutions Manual all chapters
Immediate download Programming Languages Principles and Practices 3rd Edition Louden Solutions Manual all chapters
com
https://testbankfan.com/product/programming-languages-
principles-and-practices-3rd-edition-louden-solutions-
manual/
OR CLICK HERE
DOWLOAD NOW
https://testbankfan.com/product/programming-languages-principles-and-
practices-3rd-edition-louden-test-bank/
testbankfan.com
https://testbankfan.com/product/concepts-of-programming-
languages-10th-edition-sebesta-solutions-manual/
testbankfan.com
https://testbankfan.com/product/foundation-design-principles-and-
practices-3rd-edition-coduto-solutions-manual/
testbankfan.com
https://testbankfan.com/product/thinking-about-biology-an-
introductory-laboratory-manual-5th-edition-bres-solutions-manual/
testbankfan.com
Calculus Early Transcendentals 4th Edition Rogawski
Solutions Manual
https://testbankfan.com/product/calculus-early-transcendentals-4th-
edition-rogawski-solutions-manual/
testbankfan.com
https://testbankfan.com/product/introduction-to-programming-using-
visual-basic-2012-9th-edition-schneider-solutions-manual/
testbankfan.com
https://testbankfan.com/product/aging-and-society-a-canadian-
perspectives-7th-edition-novak-test-bank/
testbankfan.com
https://testbankfan.com/product/biology-of-humans-concepts-
applications-and-issues-6th-edition-goodenough-test-bank/
testbankfan.com
https://testbankfan.com/product/statics-and-mechanics-of-
materials-2nd-edition-beer-solutions-manual/
testbankfan.com
Understanding Operating Systems 7th Edition McHoes Test
Bank
https://testbankfan.com/product/understanding-operating-systems-7th-
edition-mchoes-test-bank/
testbankfan.com
Programming Languages - Principles and Practice
3rd Edition
by Kenneth C Louden and Kenneth A. Lambert
Cengage 2011
Chapter 6
6.2. A sample test in C (or Java) would insert a comment in the middle of a reserved word, such as in
in/*comment*/t x;
This will in fact produce an error, transforming int into two tokens in and t (usually interpreted as
identifiers by a compiler). In Ada and FORTRAN, such a comment cannot be written. In Ada, all
comments begin with two adjacent hyphens and extend up to the next newline. Thus, Ada comments by
design can only occur as part of white space (a newline). In FORTRAN comments can only be entire
lines, so a similar remark holds.
6.5
(a) These are numbers with an optional exponential part: they consist of one or more digits, possibly
followed by an "e" or an "E" and an optional + or −, followed by one or more digits. Some examples are
42, 42e2, 42E−02, and 0e+111.
(b) [a-zA-Z_][a-zA-Z0-9_]*
6.6. (a) The problem is that allowing signed integer constants creates an ambiguity in recognizing tokens that
a scanner cannot resolve. For example, the string 2-3 should have three tokens: a NUMBER, a MINUS, and
a NUMBER, and the string 2--3 should also have the same three tokens (assuming signed constants are
legal). This ambiguity can only be resolved by the parser, thus creating a serious problem in writing an
independent scanner.
(b) There are several possible solutions. Perhaps the most common is to have the scanner always
recognize a minus sign as a separate token, and then extend the grammar to allow the parser to recognize
leading minus signs whenever a constant is expected. This means that, while in theory constants can
include leading minus signs, in practice they are constructed by the parser by applying a unary minus
operation at compile-time to an unsigned constant. An alternative to this strategy is to simply build the
above solution into the language definition itself: disallow signed constants and extend the grammar to
allow leading unary minuses wherever constants can appear.
6.8 There are 32 legal sentences generated by the grammar. This is because any legal sentence can be
generated from the string
and there are two choices for each of the five nonterminals, for a total of 25 = 32 choices.
Lambert and Louden Programming Languages – Principles and Practice 3rd Ed. Answers - 2
6.11. We use - for subtraction and / for division. We add these operations to the BNF and EBNF, leaving the
modification of the syntax diagrams of Figure 6.11 to the reader.
BNF:
expr → expr + term | expr - term | term
term → term * factor | term / factor | factor
factor→ ( expr ) | number
number → number digit | digit
digit → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
EBNF:
expr → term { (+ | -) term }
term → factor { (* | /) factor }
factor→ ( expr ) | number
number → digit { digit }
digit → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Note: In the EBNF we have used parentheses to group operations within pairs of brackets in the first two
rules. This makes parentheses into new metasymbols. An alternative is to write
Note that writing the first rule in the following form is incorrect (why?):
6.12
(a) expr → expr + term | term
term → term * power | term % power | power
power → factor ^ power | factor
factor → ( expr ) | number
number → number digit | digit
digit → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
6.13 (a)
BNF:
expr → expr + term | - term | term
term → term * factor | term / factor | factor
factor→ ( expr ) | number
6.14
(b) The parse tree is
expr
expr + term
digit 7
number number digit
6
digit digit 5
3 4
+ *
3 * 6 7
4 5
expr
expr + term
digit 4 5
+ 7
* *
3 4 5 6
expr
term
term * factor
digit 5 6
4
The abstract syntax tree is
*
* +
3 + 6 7
4 5
expr
term
factor
( expr )
expr + term
term factor
factor ( expr )
number
expr + term
digit
term factor
2
factor
( expr )
number
expr + term
digit
term factor
3
factor number
number digit
digit 5
2 +
3 +
4 5
6.19 (a) The changes needed occur only in expr() and term(), which now should appear as follows:
int expr()
/* expr -> term { '+' term | '-' term } */
{ int result = term();
while (token == '+' || token == '-')
{ char temp = token;
match(token);
if (temp == '+') result += term();
else result -= term();
}
return result;
}
int term()
/* term -> factor { '*' factor | '/' factor } */
{ int result = factor();
while (token == '*' || token == '/')
{ char temp = token;
match(token);
if (temp == '*') result *= factor();
else result /= factor();
}
return result;
}
6.20 (c) A new precedence level and corresponding procedure needs to be added for the power operation,
which we call power() in the following. Changes also need to be made to factor() to incorporate the
calls to power(), as well as to add the new remainder operation. These two procedures now should appear
as follows:
int term()
/* term -> power { '*' power | '/' power | '%' power } */
{ int result = power();
while (token == '*' || token == '/' || token == '%')
{ char temp = token;
match(token);
if (temp == '*') result *= power();
else if (temp == '/') result /= power();
else result %= power();
}
return result;
}
int power()
/* power -> factor [ '^' power ] */
{ int result = factor();
if (token == '^')
{ int pow, temp;
match(token);
pow = power();
temp = 1;
while (pow-- > 0) /* works only for positive powers */
temp *= result;
result = temp;
}
return result;
}
6.21 All grammar rule procedures and temporary results, except for number() and digit(), need to be
changed to double, and the output in command() needs its format changed from %d to %g or %f. Also, the
following code needs to be added (with changes indicated for the factor() code):
double factor()
/* factor -> '(' expr ')' | decimal_number */
{ double result;
if (token == '(')
{ match('(');
result = expr();
match(')');
}
else
result = decimal_number();
return result;
}
double decimal_number()
/* decimal_number -> number [ '.' frac_number ] */
{ double result = number();
if (token == '.')
{ match(token);
result += frac_number();
}
return result;
}
double frac_number()
/* frac_number -> digit [ frac_number ]
(right recursive because it computes a fractional result
more easily) */
{ double result = digit() / 10.0;
if (isdigit(token))
result += frac_number() / 10.0;
return result;
}
6.22. Writing the rule as expr → term + term allows only one + operation per expression, so that, for example,
3 + 4 + 5 would become illegal. This is not fatal to writing more than one + operation in an expression,
since parentheses can be used: the expression (3 + 4) + 5 remains legal. But it does remove the
ambiguity by changing the language recognized rather than by changing the grammar but not the
language.
6.24. (a) The changes are to the rules for expr and term only:
6.30. Suppose a declaration has the form var _;, where _ stands for any string usable as a variable
identifier. Suppose further that only two letters, say, a and b, are usable as variable identifiers. Then the
possible declarations without redeclaration are {var a;, var b;, var a; var b;, var b; var a}.
These could be generated by EBNF rules
Now suppose that c is also a legal identifier. Then instead of six legal declaration sequences there are
fifteen, and EBNF rules look as follows:
There are now four grammar rules instead of one. The grammar is growing exponentially with the
number of variables. Thus, even in a language where variables can be only two characters long, there are
nearly a thousand possible variables, and perhaps millions of grammar rules. Writing a parser for such a
grammar would be a waste of time.
6.31 A scanner can't recognize all expressions, even though an expression is a repetition of terms and plus
operators, for the following reason: a term may recursively contain expressions inside parentheses, and a
scanner cannot recognize structures that can have the same structure as a substructure.
6.32. We give here the BNF and EBNF rules. Translating the EBNF into syntax diagrams is left to the reader.
If a statement sequence must have at least one statement, the grammar rule is easily stated as the
following.
However, statement sequences usually are allowed to be empty, which complicates the problem. One
answer is to use the previous solution and a helper rule, as follows.
BNF:
statement-sequence → | statement-sequence1
statement-sequence1 → statement-sequence1 ; statement | statement
6.33 We give here the BNF and EBNF rules. If a statement sequence can be empty, we have the following
rules:
If a statement sequence must contain at least one statement, we must write the rules as follows:
6.36. (a) Here are the number of reserved words in each language:
C: 32
C++: 74
Ada: 69
Java: 47
(b) In Pascal predefined identifiers not only include the standard data types, such as integer, that
correspond to reserved words in C, but also include functions such as sin, cos, abs, chr, ord, and so
on. These correspond to standard library functions in C, C++, Ada, and Java. The problem with Pascal is
compounded by the fact that Pascal has no separate compilation or standard libraries, while C has a
small set of standard libraries, and Ada, C++ and Java (particularly Java) have very large standard
libraries. Of course, to be at all useful even C must have libraries comparable to C++ or Java or Ada –
it's just that these libraries are all non-standard (such as the Windows C API, for example). Thus just
adding library identifiers alone is still misleading. Perhaps one should add all predefined identifiers and
standard library identifiers to have a fair comparison, but in the modern world of large standard libraries
these numbers are very large (in the thousands). If one wishes to get an idea only of the complexity of a
language parser, rather than the language as a whole, then counting reserved words does do that.
6.38. Indeed, FORTRAN is a language without reserved words, so it is certainly possible for a language to
have no reserved words. The problem is that all language constructs become essentially context
dependent, and a parser cannot decide which construct is applicable without help from the symbol table
and semantic analyzer. This enormously complicates the parsing process, and context-free grammar
techniques cannot be used. For this reason, the trend has been toward greater use of reserved words and
less use of predefined identifiers in the definition of the basic syntax of a language.
6.40. The difference is immaterial in terms of recognizing numbers. The parse tree becomes significant only
if the tree itself is used for further translation or computation. In the case of a number, the main "further
translation" that is needed is to compute its value. If we try to compute its value recursively, based on the
structure of the tree, we notice a difference in complexity between the two tree structures. Consider, for
example, the number 234. It has the two possible parse trees
number number
digit 3 3 digit
2 4
In the left-hand tree, at a number node with two children, its value can be computed by multiplying the
value of its left child by 10 (in base 10) and adding the value of its right child. In the right-hand tree, a
more complex computation is required, namely, the number of digits in each value must also be
computed. For example, to compute the value of the root of the right-hand tree, the value of its left child
(2) must be multiplied by 100 = 102 (the exponent 2 = the number of digits of its right child), and then
added to the value of its right child (34). Thus the left-hand tree, which resulted from the left-recursive
rule, is to be preferred. This is an example of the principle of syntax-directed semantics.
6.42
(a) EBNF rules are
expr → ( list ) | a
( list )
expr
list
expr
(b)
expr
( list )
list , expr
expr a expr
( list ) a
list , expr
expr a
(c) In C-like pseudocode, a recursive-descent recognizer is as follows (using a global variable token, a
global match procedure, and global procedure error that prints an error message and exits) :
void expr()
{ if (token == 'a') match('a');
else if (token == '(')
{ match('(');
list();
match(')');
}
else error();
}
void list()
{ expr();
while (token == ',')
{ match(',');
expr();
}
}
6.43. (a) There are no precedences or associativities in abstract syntax because the structure of the syntax
expression (or syntax tree) itself will provide the order in which the operations to be applied.
(b) There are no parentheses because parentheses are useful only to change associativity and precedence,
and by (a) these are non-issues in abstract syntax.
(c) There is no inherent tree structure in numbers: they are just sequences of digits. Thus, a sequential
representation as in EBNF is appropriate. This is, of course, not true for expr, since there are two
subexpressions possible, and this can lead to many distinct tree structures (corresponding to associativity
and precedence rules).
6.49. (a) The first condition of predictive parsing is satisfied by the grammar, since the first grammar rule is
the only one with an alternative, and
To show that the second condition for predictive parsing is satisfied, we must show that First( list )
Follow( list ) = , since list is optional in the second grammar rule. We first compute First( list ). By the
second grammar rule, First( list ) contains First( expr ). Since this is the only contribution to First( list ),
we have First( list ) = First( expr ), and from the first grammar rule we have First( expr ) = { ( , a }, so
First( list ) = { ( , a }. To compute Follow( list ), we note that the first grammar rule shows that ) can
follow a list. The second grammar rule gives us no additional information (it tells us only that Follow(
list ) contains Follow( list )), so Follow( list ) = { ) }. Then
(b) C code for expr and list recognizers are as follows (using the same conventions as Figure 6.24):
void expr()
{ if (token = '(')
{ match('(');
list();
if (token == ')') match(')', ") expected");
else error();
}
else if (token == 'a') match('a', "a expected");
else error("illegal expression");
}
void list()
{ expr();
if (token == '(' || token == 'a') list();
}
Note that in the code for list we used First( list ) to decide whether to make the optional recursive call
to list. We could just as well have used the Follow set (which will, however, give a slightly different
behavior in the presence of errors):
void list()
{ expr();
if (token != ')') list();
}
Spokane has a rare climate of cloudless days. The Indians say that
once it shared the fogs and copious rains of the seacoast, but that
their tutelary god, ascending to the heavens, slew the Thunderer,
and that thenceforth they dwelt under radiant skies, and were called
Spokanes, or Sons of the Sun.
A college of artists could not have devised a more beautiful location
for a city. It is set in a gigantic amphitheatre two thousand feet
above sea level. High walls of basalt, picturesque with spruce and
cedar and pine, form the city's rim. Against this background have
been built mansions that would adorn Fifth Avenue or the Circles of
the national capital. Forming the city's southern border winds an
abysmal gorge, and along its brink has been built one of the city's
fashionable boulevards. The cataracts of the Spokane some day
must inspire poets. In some parts of the city, affording adornments
for numberless gardens, are volcanic, pyramidal rocks. The Indians
say that these columns are the petrified forms of amazons who,
issuing from the woods, were about to plunge into the river for a
bath, ignorant of the water demon, when Speelyai to save them
turned them into stone.
It is significant of the lure of Spokane that men who have
accumulated millions and sold their mines still make it their place of
permanent residence. Though the city as it is to-day has been built
in the dozen years that have elapsed since its great fire, there is no
hint of hasty development within its boundaries. Singular fertility in
its soil has so fostered its shade trees and its gardens that a sense is
conveyed of years of affluent ease and attention to æsthetic detail.
Spokane is in many respects the most consummate embodiment on
the continent of that typical American genius that has redeemed the
wilderness of the frontier.
PORTLAND
By THOMAS L. COLE
Jefferson, who had sent out the Lewis and Clark expedition, heartily
endorsed this project, as did also his Cabinet. In prosecution of
Astor's purpose, on April 12, 1811, the Tonquin, the precursor of an
intended "annual vessel," bringing partners, clerks, voyageurs, and
artisans, as well as material and merchandise, crossed the bar of the
Columbia and cast anchor. Point George, as it had been named by
Broughton, was selected as a site for the embryo metropolis, and
was renamed Astoria, after the great commoner whose enterprise it
represented. Here, after the Tonquin had sailed away to its tragic
fate, the little colony proceeded to establish itself. A fort, a stone
mansion, and other buildings were erected, and a schooner, the
Dolly, was constructed and launched. The colonists did some trading
with the neighboring Indians but delayed to reach out into the
surrounding country until the arrival of Wilson Price Hunt, who was
bringing an expedition overland and was to establish suitable trading
posts en route. Hunt, who was an American and the chief partner
under Mr. Astor, was to be in charge at Astoria. While engaged in
their work of construction, the colonists were disturbed by rumors
that their rivals, the Northwest Company, had entered their territory
and established a post on the Spokane River. This rumor was
confirmed when a canoe came down the Columbia flying the British
standard, and a gentleman, stepping ashore, introduced himself as
David Thompson, an astronomer and a partner of the Northwest
Company. McDougal, who was temporarily in charge, was, like
several of Astor's partners, a Scotchman, and a former Northwest
employé. This visitor, therefore, was treated as an honored guest
instead of as a spy, which he really was. However, it was determined
that David Stuart should at once take a small party and set up a post
as a check to the one on the Spokane, which he did at Oakinagen.
ASTORI
A IN
1811.
BASED
ON A
PRINT
IN
GRAY'S
"HISTO
RY OF
OREGO
N."
VIEW
OF
PORTL
AND,
1900.
By EDWIN MARKHAM