CMPS 144L Summer 2020
Lab #5: FPAE's and Stacks

Background

As you should recall from lecture, an FPAE (fully-parenthesized arithmetic expression) is either an integer literal (e.g., "605") or of the form

( E op F )

where E and F are themselves FPAE's and op is a binary infix arithmetic operator (i.e., one of +, , *, or /).

Thus, an FPAE is composed of (up to) four kinds of elements, or tokens: left parentheses, right parentheses, integer literals, and operators. FPAE's that are integer literals are said to be atomic, while those that include one or more operators are said to be composite. Intuitively, an FPAE is an arithmetic expression in which every composite subexpression is explicitly parenthesized. It follows that, in an FPAE, the number of pairs of mated parentheses is equal to the number of operators.

In order to make it easy to identify the individual tokens of an FPAE using a Scanner object (i.e., an instance of the class java.util.Scanner), we will assume that consecutive tokens in an FPAE are separated by one or more spaces.

Examples of FPAE's:

57 ( ( 5 + 2 ) * ( 72 - ( 8 / 3 ) ) )
( 3 - 15 ) ( ( ( 7 + 9 ) * 10 ) / ( ( 4 * 16 ) / ( 25 - 13 ) ) )


Your task is to complete the FPAE_Utils class. Its two public methods are incomplete, and you are to put them into working order. One of them, isWellFormed(), determines whether or not the String passed to it qualifies as a well-formed (i.e., syntactically correct) FPAE. The other one, valueOf(), evaluates the FPAE passed to it, which is assumed to be well-formed.

Several other methods that you should find useful are provided within the class, including a main() method for the purpose of testing your work. The Integer.parseInt() method, which translates a numeral (i.e., a String that is a sequence of decimal digit characters) into the corresponding value of type int, will be vital, too.

You also are given the complete Java class StackViaArray, of which FPAE_Utils is a client. For an example of a client program of StackViaArray, see the ParenthesisMatcher application


isWellFormed()

To determine whether or not a string is a well-formed FPAE, this method uses a stack to hold integer codes that represent left parentheses, operators, and operands.1 You will notice the declarations of the int constants LEFT_PAREN_CODE, OPERATOR_CODE, and OPERAND_CODE in the method.

Here is how the method should work:
As it scans the string from left to right, it pushes onto the stack the integer codes corresponding to any tokens that are not right parentheses. When it encounters a right parenthesis, it pops the stack four times and verifies that what came out were the codes for, respectively, an operand, an operator, an operand, and a left parenthesis. If there is any deviation from this (or if the stack had fewer than four items on it in the first place), the string is not a well-formed FPAE. If, on the other hand, what came out of the stack meets this expectation, it pushes onto the stack the code for an operand and continue scanning.

Assuming that everything has gone well to the point that the last token has been processed, all that remains to verify is that the stack has exactly one element on it and that element is the code for an operand. Otherwise, the string is not a well-formed FPAE.


valueOf()

Consistent with what was demonstrated in lecture, this method uses two stacks, one of which holds operators that have been encountered (but have not been applied yet, because their corresponding right parentheses are yet to be encountered). The other stack holds the values of subexpressions (i.e., operands) that have been evaluated already and that are waiting to have an operator applied to them.

Here is how the method should work:

After the last token is processed, the operator stack necessarily will be empty and the operand stack necessarily will have exactly one value in it, and that will be the value of the FPAE.


Footnotes

[1] An operand is, in effect, a subexpression all of whose tokens already have been processed. Another way to look at it is that an operand is a subexpression that, had we been evaluating the FPAE instead of checking its well-formedness, already would have been evaluated, and thus reduced to an integer literal.