introduction to parsing want_infowant_filename range( state want_info the open file object is in variable fh if the file doesn' start with the correct text for file we output an error message and return an empty list the song named tuples will be stored in the songs list the regex is for matching the bnf' info nonterminal the parser itself is always in one of two stateseither want_info (the start stateor want_filename in the want_info state the parser tries to get the title and secondsand in the want_filename state the parser creates new song and adds it to the songs list for linoline in enumerate(fhstart= )line line strip(if not linecontinue we iterate over each line in the given open file object in similar way to what we did for the pls parser in the previous subsectiononly this time we start the line numbers from since we handle line before entering the loop we strip whitespace and skip blank linesand do further processing depending on which state we are in if state =want_infoinfo info_re match(lineif infotitle info group("title"seconds int(info group("seconds")state want_filename elseprint("failed to parse line { }{ }formatlinoline)if we are expecting an info line we attempt to match the info_re regex to extract the title and the number of seconds then we change the parser' state so that it expects the next line to be the corresponding filename we don' have to check that the int(conversion works ( by using try except)since the text used in the conversion always matches valid integer because of the regex pattern (-?\ +elif state =want_filenamesongs append(song(titlesecondsline)title seconds none state want_info if we are expecting filename line we simply append new song with the previously set title and secondsand with the current line as the filename