Saturday, October 25, 2014

Parser – Exceptions

When an error was detected, the parser set its internal error status to an enumerator for the error (either unknown token or a number error) and returned a an error token with its column and length set to the error.  So to return an exception, the status, column and length values need to be included in the exception thrown.  A simple Error structure was added to hold this information.  The parser routines were modified to throw an error exception when detecting an error.  The necessary values are included for this structure:
throw Error {Status::Error, m_token->column(), m_token->length()};
The set error functions were removed along with the error status member and its access function.  Since the Error token type enumerator doesn't indicate an error token anymore, this enumerator was removed.  The table entries that used with enumerator were changed to the default token enumerator (required the first enumerator to be set to 1).  A leftover check in the get identifier routine was removed that set the token string to  "invalid two work command" for an error token type, but this won't occur.

The translator get token routine was modified to catch parser exceptions (using C++ try and catch blocks).  For no exception, the Good status enumerator is returned.  For an exception, an error token is created from the column and length in the error structure.  (The token constructor was modified with an additional length argument and to the C++ initializer syntax.)  The rest of catch section remains the same except the status in the error structure is returned.  The creation of an error token may be removed later if the translator is modified to the exception model for handling errors.

The tester parse input routine was also modified to catch parser exceptions.  The while loop was replaced with a forever loop and the more flag removed.  For no exception, the print token routine is called.  The routine continues with the next token unless an End-of-Line token was returned.  For an exception, the print error routine is called directly, and the routine returns immediately.  The use of exceptions in the parse input routine allowed some simplifications in these print routines.

The print token previously had an error status argument.  If the token type was an error, then the error status was passed to the print error routine with the token column and length.  This check and call was removed, and so was the error status argument.  The tab argument was always true, so it was also removed.  The column, length and status arguments of the print error function were replaced with an error structure reference argument.  This required creating a temporary error structure in the translate input and encode input routines (perhaps later the translator will be modified to throw an error and the program module modified to return an error structure).

It should be noted that the token created at the beginning of the parser function operator routine if left allocated when an exception is thrown.  Previously the token is moved to the caller when the token contained an error the same as with a good token.  This is not a problem because the parser will go out of scope once the translator handles the error and returns.  The parser routines may be able to be changed to only create a token when a good token is found.  This will be considered as the parser is changed to use the STL.

[branch parser commit 14265956f7]

No comments:

Post a Comment

All comments and feedback welcomed, whether positive or negative.
(Anonymous comments are allowed, but comments with URL links or unrelated comments will be removed.)