cs205: engineering software? |
(none) 20 September 2010 |
Element ::= ReplacementThis rule means whenever Element appears, it can be replaced with Replacement.
Elements that appear on the left side of any rule are called non-terminals. This means they do not appear in an utterance in the language. Elements that appear only on the right side of rules are called terminals. We use Italics for non-terminals and bold for terminals.
For example,
ArgumentList ::=describes a non-terminal ArgumentList that expands to a comma-separated list of expressions. We can replace ArgumentList with noting (the first rule), or with a NonEmptyArgumentList (the second rule). We can replace a NonEmptyArgumentList with either a single Expression (first rule) or an Expression followed by a , and a NonEmptyArgumentList. Note that the recursive definition means we can describe argument lists of any length using a few simple replacement rules. We can keep using the fourth rule to add additional Expressions to an ArgumentList.
ArgumentList ::= NonEmptyArgumentList
NonEmptyArgumentList ::= Expression
NonEmptyArgumentList ::= Expression , NonEmptyArgumentList
There are three different kinds of calls in Java: constructors, methods, and static methods.
Expression ::= new ClassName ( argumentList )Creates a new object of type ClassName. For example, to use the constructor specified as
ClassName ::= Identifier
ClassName ::= PackageName . Identifier
PackageName ::= Identifier
PackageName ::= PackageName . Identifier
public class Set { ... public Set() EFFECTS: Initializes this to an empty set: {}we would do:
new Set()
This would typically be used in an initialization statement:
Statement ::= VariableDeclaration ;For example,
VariableDeclaration ::= OptModifier Type Identifier OptInitializer
Type ::= ClassName
Identifier ::= a valid Java identifier
OptInitializer ::=
OptInitializer ::= = Expression
Set s = new Set();initializes s to the object created by the Set constructor.
Expression ::= MethodCallThe Reference is an expression that evaluates to an object. This object is the this object of the method invocation.
MethodCall ::= Reference . MethodName( ArgumentList )
Reference ::= Expression MethodName ::= Identifier
For example, to invoke the method specified in the Set class below:
public void insert (String el) // MODIFIES: this // EFFECTS: Adds el to the elements of this.we need a Set object for the Reference and a String object for the argument:
Set s = new Set(); s.insert("alice");Consider the method call,
System.out.println("Hello");The Reference is System.out, the MethodName is println and the ArgumentList is "Hello".
Sometimes the reference object for a method call is not shown explicitly:
MethodCall ::= MethodName( ArgumentList )There is no explicit Reference, but there is still a reference object. When there is no explicit reference, there is an implicit this reference object. So, the MethodCall syntax above is an abbreviation for:
MethodCall ::= this . MethodName( ArgumentList )Here's an example from the union method implementation in the Set class:
public void union (Set t) // MODIFIES: this // EFFECTS: this_post = this_pre U t { for (String el : t.elements()) { insert(el); // short for: this.insert(el); } }
MethodCall ::= ClassName . MethodName( ArgumentList )For example, System.exit(0) invokes the static method exit in the System class.
Statment ::= TryStatementThe execution executes the statements in the try block. If no exception is raised, execution continues to the statements in the finally block if there is one, or to the next statement otherwise. If an exception is raised, execution jumps to the catch clauses. The catch clauses are examined in order, until one is found that matches the type of the execption. Then, the statements in the matching catch block are executed. After the catch, the execution continues to the statements in the finally block if there is one, or to the next statement otherwise.
TryStatement ::= try { StatementList } CatchBlocks FinallyBlock
CatchBlocks ::=
CatchBlocks ::= catch (Type Identifier) { StatementList }
CatchBlocks
FinallyBlock ::= finally { StatementList }
StatementList ::=
StatementList ::= Statement StatementList
Here's an example:
Scanner s = null; try { s = new Scanner(new File(args[0])); } catch (FileNotFoundException fnfe) { userError("Unable to open file: " + fnfe); }The statement in the try block calls a Scanner constructor to create a new scanner object. The specification for the Scanner constructor,
public Scanner(File source) throws FileNotFoundException // EFFECTS: If the source if not found, throws FileNotFoundException. Otherwise, // initializes this to a new Scanner corresponding to the file source.indicates that it may throw the FileNotFoundException. The catch clause handles this exception. The variable fnfe in the catch clauses holds the value of the thrown exception. The catch clause statement calls the userError static method to report an error.
Statement ::= ThrowStatementThe Expression in a ThrowStatment must evaluate to an object of type Throwable. Typically, this will be a newly constructed exception object:
ThrowStatement ::= throw Expression ;
public class Set { ... public String choose() throws EmptyException // EFFECTS: If this is empty, throws EmptyException. Otherwise, // returns an element of this. { if (size() == 0) { throw new EmptyException(); } ... }Where EmptyException is an exception class defined in EmptyException.java:
public class EmptyException extends Exception { static final long serialVersionUID = 0L; // Needed to avoid compiler warning. public EmptyException () { super (); } }(For now, it is okay to use this as a "cookbook" structure for creating your own exception types. Later we will understand more what this is doing.)
Statement ::= WhileStatementA ForStatement can be rewritten as an equivalent WhileStatement:
WhileStatement ::= while ( Expression ) Statement
Statement ::= ForStatement
ForStatement ::= for ( InitializationExpression ; TestExpression ; UpdateExpression ) Statement
for ( InitializationExpression ; TestExpression ; UpdateExpression ) StatementThe InitializationExpression is executed first. Then, if the TestExpression evaluates to true, the Statement is executed, followed by the UpdateExpression. After the update, execution continues with the TestExpression again. This continues until the TestExpression evaluates to false.
==> InitializationExpression ; while (TestExpression) { Statement UpdateExpression; }
Withing the loop body statement, we can use two statements to alter execution:
Statement ::= break ;The break statement exits from the containing loop block. After a break statement, execution continues at the statement following the looping statement. The continue statment jumps to the update expression (in a for loop), or the test expression (in a while loop). It continues to the next iteration of the loop.
Statement ::= continue ;
Here's an example from the TaskScheduler code:
while (linescanner.hasNext()) { String dname = linescanner.next(); if (dname.equals("}")) { gotbrace = true; break; } depends.add(dname); }
An enhanced for statment supports iteration through a collection:
Statement ::= IterationStatementThe Expression must evaluate to an object that supports iteration. This includes any arry instance, as well as any object of a class that implements the Iterable interface (we'll cover what this means a bit later, but for now assume all the collection classes support it). The Identifier is a variable that will be initialized to each value in the collection in turn in each iteration of the loop.
IterationStatement ::= for ( Type Identifier : Expression) Statement
For example,
static int sum(int [] values) { int total = 0; for (int val : values) total += val; return total; }We can also use this to iterate through the elements of a Vector, as in the union implementation above.
The java.util package defines many useful classes for managing collections of objects. These classes take type parameters that specify the type of objects in the collection. The collection classes provided by Java are not good data abstractions — their specifications (and even their names) include details about how they are implemented. For example, there are three different Set datatypes: HashSet, TreeSet, and LinkedHashSet. The implement essentially the same abstraction, but with different performance characteristics; the best one to use depends on what values will be in the set and the commonly used operations. Useful collection classes include:
To use any of these classes, you need to import them:
import java.util.Vector; import java.util.HashMap;then, declare a variable with the type parameters specified:
private HashMap<String, Vector<String>> table;declares table as a HashMap where the keys are of type String and the values are of type Vector<String>.
So, when we call the put method specified as:
public V put (K key, V value) // EFFECTS: Associates the specified value with the specified key in this map. // If the map previously contained a mapping for this key, the old value is replaced. // Returns the previous value associated with the key, or null if there was no // previous mapping.we would pass in a String and a Vector<String> object as the arguments.