the important feature of this parser is the process methodwhich accepts the remaining stringand passes it off to the current state the parser (the self argumentis also passed into the state' process method so that the state can manipulate it the state is expected to return the remainder of the unparsed string when it is finished processing the parser then recursively calls the process method on this remaining string to construct the rest of the tree nowlet' have look at the firsttag stateclass firsttagdef process(selfremaining_stringparser)i_start_tag remaining_string find('<'i_end_tag remaining_string find('>'tag_name remaining_string[i_start_tag+ :i_end_tagroot node(tag_nameparser root parser current_node root parser state childnode(return remaining_string[i_end_tag+ :this state finds the index (the i_ stands for indexof the opening and closing angle brackets on the first tag you may think this state is unnecessarysince xml requires that there be no text before an opening tag howeverthere may be whitespace that needs to be consumedthis is why we search for the opening angle bracket instead of assuming it is the first character in the document note that this code is assuming valid input file proper implementation would be rigorously testing for invalid inputand would attempt to recover or display an extremely descriptive error message the method extracts the name of the tag and assigns it to the root node of the parser it also assigns it to current_nodesince that' the one we'll be adding children to next then comes the important partthe method changes the current state on the parser object to childnode state it then returns the remainder of the string (after the opening tagto allow it to be processed the childnode statewhich seems quite complicatedturns out to require nothing but simple conditionalclass childnodedef process(selfremaining_stringparser)stripped remaining_string strip(if stripped startswith("</")parser state closetag(