code: protected void report(LocatedException error, VDMToken[] after,
  			VDMToken[] upto)
  	{
  		VDMError vdmerror = new VDMError(error);
  		errors.add(vdmerror);
  
  		if (errors.size() >= MAX - 1)
  		{
  			errors.add(new VDMError(9, "Too many syntax errors", error.location));
  			throw new InternalException(9, "Too many syntax errors");
  		}
  
  		// Either leave one token beyond something in the after list, or
  		// at something in the next upto list.
  
  		List<VDMToken> afterList = Arrays.asList(after);
  		List<VDMToken> uptoList = Arrays.asList(upto);
  
  		try
  		{
  			VDMToken tok = lastToken().type;
  
  			while (!uptoList.contains(tok) && tok != VDMToken.EOF)
  			{
  				if (afterList.contains(tok))
  				{
  					nextToken();
  					break;
  				}
  
  				tok = nextToken().type;
  			}
  		} catch (LexException le)
  		{
  			errors.add(new VDMError(le));
  		}
  	}
docs: Raise a syntax error and attempt to recover. The error is added to the errors list, and if this exceeds 100
  errors the parser is aborted. The "after" and "upto" lists of token types are then used to control the advance of
  the parser to skip beyond the error. Tokens are read until one occurs in either list or EOF is reached. If the
  token is in the "after" list, one more token is read before returning; if it is in the "upto" list, the last
  token is left pointing to the token before returning. If EOF is reached, the method returns.
  
  @param error
  The exception that caused the error.
  @param after
  A list of tokens to recover to, and step one beyond.
  @param upto
  A list of tokens to recover to.