Java Reference
In-Depth Information
own source. Thus we repeatedly digest characters. If the current character is a
closing quote, we are done. If it is a newline, we have an unterminated charac-
ter or string constant. And if it is a backslash, we digest an extra character
without examining it.
Once we've written the skipping routine, writing getNextOpenClose is eas-
ier. The bulk of the logic is deferred to processSlash . If the current character is
a / , we read a second character to see whether we have a comment. If so, we
call skipComment ; if not, we undo the second read. If we have a quote, we call
skipQuote . If we have an opening or closing symbol, we can return. Other-
wise, we keep reading until we eventually run out of input or find an opening
or closing symbol. Both getNextOpenClose and processSlash are shown in
Figure 11.7.
The getLineNumber and getErrorCount methods are one-liners that return
the values of the corresponding data members and are shown in Figure 11.2.
We discuss the getNextID routine in Section 12.2.2 when it is needed.
In the Balance class, the balanced symbol algorithm requires that we place
opening symbols on a stack. In order to print diagnostics, we store a line num-
ber with each symbol, as shown previously in the Symbol nested class at lines
34 to 44 in Figure 11.3.
The checkBalance routine is implemented as shown in Figure 11.8. It fol-
lows the algorithm description almost verbatim. A stack that stores pending
opening symbols is declared at line 9. Opening symbols are pushed onto the
stack with the current line number. When a closing symbol is encountered and
the stack is empty, the closing symbol is extraneous; otherwise, we remove
the top item from the stack and verify that the opening symbol that was on the
stack matches the closing symbol just read. To do so we use the checkMatch
routine, which is shown in Figure 11.9. Once the end of input is encountered,
any symbols on the stack are unmatched; they are repeatedly output in the
while loop that begins at line 40. The total number of errors detected is then
returned.
The current implementation allows multiple calls to checkBalance . How-
ever, if the input stream is not reset externally, all that happens is that the end
of the file is immediately detected and we return immediately. We can add
functionality to the Tokenizer class, allowing it to change the stream source,
and then add functionality to the Balance class to change the input stream
(passing on the change to the Tokenizer class). We leave this task for you to do
as Exercise 11.9.
Figure 11.10 shows that we expect a Balance object to be created and then
checkBalance to be invoked. In our example, if there are no command-line argu-
ments, the associated Reader is attached to System.in (via an InputStreamReader
bridge); otherwise, we repeatedly use Reader s associated with the files given in
the command-line argument list.
The checkBalance
routine does all the
algorithmic work.
 
Search WWH ::




Custom Search