control structures and functions the function has various statesfor exampleafter reading an ampersand (&)it enters the parsing_entity stateand stores the characters between (but excludingthe ampersand and semicolon in the entity string set type the part of the code shown here handles the case when semicolon has been found while reading an entity if the entity is numeric (of the form "&#"with hexadecimal digitsand then ";"for example"&# ac;")we convert the numeric part of it into set and take away from the set all the hexadecimal digitsif anything is left at least one invalid character was present and we raise custom exception if the entity is alphabetic (of the form "&"with lettersand then";"for example"&copy;")we raise custom exception if any of its letters is not alphabetic except (invalidentityerrorinvalidtagcontenterroras errif isinstance(errinvalidnumericentityerror)error "invalid numeric entityelif isinstance(errinvalidalphaentityerror)error "invalid alphabetic entityelif isinstance(errinvalidtagcontenterror)error "invalid tagprint("error { in { on line { column { }format(errorfilenamelinocolumn)if skip_on_first_errorraise if parsing exception is raised we catch it in this except block by using the invalidentityerror base classwe catch both invalidnumericentityerror and invalidalphaentityerror exceptions we then use isinstance(to check which type of exception occurredand to set the error message accordingly the built-in isinstance(function returns true if its first argument is the same type as the type (or one of that type' base typesgiven as its second argument we could have used separate except block for each of the three custom parsing exceptionsbut in this case combining them means that we avoided repeating the last four lines (from the print(call to raise)in each one the program has two modes of use if skip_on_first_error is falsethe program continues checking file even after parsing error has occurredthis can lead to multiple error messages being output for each file if skip_on_first_error is trueonce parsing error has occurredafter the (one and onlyerror message is printedraise is called to reraise the parsing exception and the outer (per-filetry block is left to catch it isinstance(