Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #37738

Re: Two exceptions

From Eric Sosman <esosman@comcast-dot-net.invalid>
Newsgroups comp.lang.java.programmer
Subject Re: Two exceptions
Date 2017-12-08 18:21 -0500
Organization A noiseless patient Spider
Message-ID <p0f6p8$256$1@dont-email.me> (permalink)
References <p0f54o$n5f$1@gioia.aioe.org>

Show all headers | View raw


On 12/8/2017 5:53 PM, Victor Porton wrote:
> I am writing something like a recursive descent parser: That is, I inspect
> object and its parts. When a part of an object is wrong, my method parse()
> throws my exception ParseException. It is sometimes handled in parse() of a
> higher-level object.
> 
> Example:
> 
> An object X may be either X1 or X2 or X3 class.
> 
> I try to call parse() for an object of X1 class. If it parses, the higher
> level parse() (for X) return X1 casted to X. If it fails with exception
> ParseException, X2 is tried, and if that fails too X3 is tried.
> 
> Or for an object X I try calling parse() for subobjects Y and Z. If either
> throws ParseException, the parse exception is propagated for parse() of X.
> 
> In this way, I consider an object and its possible parts. This is sometimes
> called recursive descent.
> 
> But I want also FatalParseException meant to stop parsing of a file
> altogether if it happens in the object or its subobject.
> 
> Human logic suggests that FatalParseException is a kind of ParseException
> and so should be its subclass. But this way handling ParseException we would
> also handle FatalParseException what is wrong, because FatalParseException
> is meant to be handled only in the outer method, outside of all parse()
> methods.
> 
> So I have two alternatives:
> 
> 1. Derive ParseException from FatalParseException what seems to do the right
> thing but seems illogical.
> 
> 2. Not derive either of these two exceptions from each other.
> 
> By the way, I am to rewrite an Ada project in Java (because the Ada compiler
> is too buggy and I can't work with it). In Ada all exceptions are
> independent (no exception is a subclass of another one).

     Alternative #1 seems preferable (to me).  Perhaps you would find it
more palatable if you renamed FatalParseException to ParseFailure and
ParseException to ParseMismatch.

     However, I feel you may be misusing exceptions.  They are supposed
to be, well, "exceptional" rather than "normal control flow."  In a
recursive descent parser you *expect* many matching failures, just in
the ordinary course of events; a matching failure is not "exceptional."
(Also, building a Throwable can be rather expensive, especially if it
is thrown from a deep point in the call stack and must fill in a long
stack trace.  Java's optimizations tend to focus on the "normal" cases
rather than on the "exceptional" ones, so throwing and catching, even
though much improved since Java 1.0, still involves a lot of work.)

     Instead of announcing a "venial" mismatch by throwing an exception,
consider returning a status value from each parse method.  This might
be a boolean ("It's an X1" / "It's not an X1") or a reference value
("It's an X1 and here it is" / "It's not an X1 and here's a null"),
or something more structured ("Here's a status-and-result-and-info
object; look at its fields to find out what happened").  Not only is
this likely to produce faster code, but it may also simplify

	X result;
	try {
	    result = X1.parse();
	} catch (ParseMismatch ex1) {
	    try {
	        result = X2.parse();
	    } catch (ParseMismatch ex2) {
	        try {
	            result = X3.parse();
	        } catch (ParseMismatch ex3) {
	            ...
	}

to something more like

	X result = X1.parse();
	if (result == null)
	    result = X2.parse();
	if (result == null)
	    result = X3.parse();
	...

(You could, of course, nest these differently.)

     Perhaps the structure of the existing Ada code is not amenable
to this sort of transformation -- but if I were you I'd give it
some consideration.

-- 
esosman@comcast-dot-net.invalid
Eleven hundred thirty-nine days to go.

Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Two exceptions Victor Porton <porton@narod.ru> - 2017-12-09 00:53 +0200
  Re: Two exceptions Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-12-08 18:21 -0500
    Re: Two exceptions Victor Porton <porton@narod.ru> - 2017-12-09 01:55 +0200
      Re: Two exceptions Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-12-09 07:39 -0500
        Re: Two exceptions Victor Porton <porton@narod.ru> - 2017-12-10 02:39 +0200
          Re: Two exceptions Victor Porton <porton@narod.ru> - 2017-12-10 02:46 +0200
          Re: Two exceptions Kiwi User <martin@mydomain.invalid> - 2017-12-10 00:52 +0000
      Re: Two exceptions Patrick Roemer <sangamon@netcologne.de> - 2017-12-09 13:47 +0100
  Re: Two exceptions Arne Vajhøj <arne@vajhoej.dk> - 2017-12-08 18:49 -0500
    Re: Two exceptions v_borchert@despammed.com (Volker Borchert) - 2017-12-09 07:53 +0000
  Re: Two exceptions Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-12-09 14:55 -0500
    Re: Two exceptions Patrick Roemer <sangamon@netcologne.de> - 2017-12-11 15:09 +0100

csiph-web