This is based on Programming Problem 9 in our Java text book.
Infix expressions are ones in which the operator appears between the two operands, like
In Programming Problem 9, a simple grammar defines a language that is a subset of infix expressions. In this language, single letters are used instead of numbers, and the available operators are +, -, * and /. Also, pairs of parentheses can be included.
Here is the grammar, repeated from the text book.
Your goal for this recitation is to finish the following Java code for recognizing strings in this language. It is fairly straightforward to handle the all of the grammar rules on a single line with a single method.
Study the following incomplete code. It is missing the implementation
of the validTerm method that handles the rules in the second line
of the above grammar.
Try to implement this method for 15 minutes on your own. Then discuss it as a class as the TA guides you to the answer.
Your final version should correctly process the examples included in
the main method. The output should look like:
Valid: a + b Valid: a * b - c Valid: a * ( b + c ) Valid: d / ( f + g ) Not Valid: a + b z Not Valid: a * Not Valid: x + Not Valid: a + ( b - c Not Valid: * b + c Valid: ( a + ( b * ( c / ( x - y ) ) ) ) Not Valid: ( a + ( b * c / ( x - y ) ) ) )
import java.lang.Character; // for isLetter() public class Infix { public static char[] tokens; // character array of tokens from an expression public static int current; // index into tokens showing next token to deal with // Precondition: Receives expression as a String, with spaces between each token // Postcondition: static characer array 'tokens' contains the single-character tokens // given in the argument expression string. Also, static variable 'count' // is set to zero. Returns result of validExpressionRec(true). public static boolean validExpression(String expression) { String [] tokenStrings = expression.split(" "); tokens = new char[tokenStrings.length]; for (int i = 0; i < tokenStrings.length; i++) tokens[i] = tokenStrings[i].charAt(0); current = 0; return validExpressionRec(true); } // Precondition: static array 'tokens' contains all expression tokens and 'current' is // index into 'tokens' of next token to process. Argument 'top' is true if // called at the top level of processing an expression; it is false if called // recursively from validFactor(). // Postcondition: Returns true if expression starting from 'current' contains a valid expression, // defined by these grammar rules: // <expression> = <term> | <term> + <term> | <term> - <term> // 'current' is updated to be index of next token to process. public static boolean validExpressionRec(boolean top) { boolean valid = false; if (validTerm()) { if (current < tokens.length && (tokens[current] == '+' || tokens[current] == '-')) { current++; valid = validTerm(); } else { valid = true; } } if (top) // If called at top level, make sure there are no extra tokens. return valid && current == tokens.length; else return valid; } // Precondition: static array 'tokens' contains all expression tokens and 'current' is // index into 'tokens' of next token to process. // Postcondition: Returns true if expression starting from 'current' contains a valid term, // defined by these grammar rules: // <term> = <factor> | <factor> * <factor> | <factor> / <factor> // 'current' is updated to be index of next token to process. public static boolean validTerm() { // NOT FINISHED!!! return false; } // Precondition: static array 'tokens' contains all expression tokens and 'current' is // index into 'tokens' of next token to process. // Postcondition: Returns true if expression starting from 'current' contains a valid factor, // defined by these grammar rules: // <factor> = <letter> | ( <expression> ) // <letter> = a | b | ...| z // 'current' is updated to be index of next token to process. public static boolean validFactor() { if (current >= tokens.length) return false; if (Character.isLetter(tokens[current])) { current++; return true; } if (tokens[current] == '(') { current++; if (validExpressionRec(false)) if (current < tokens.length && tokens[current] == ')') { current++; return true; } } return false; } // -------------------------------------------------------------------------------- // ---------------------------main------------------------------------------------- // -------------------------------------------------------------------------------- public static void main(String [] args) { // Expressions to be analyzed. String [] expressions = {"a + b", "a * b - c", "a * ( b + c )", "d / ( f + g )", "a + b z", "a *", "x +", "a + ( b - c","* b + c", "( a + ( b * ( c / ( x - y ) ) ) )", "( a + ( b * c / ( x - y ) ) ) )"}; // Check validity of each expression for (String exp : expressions) { if (validExpression(exp)) System.out.println("Valid: " + exp); else System.out.println("Not Valid: " + exp); } } }