#extm #extinf: ,blondie atomic blondie\atomic\ -atomic ogg #extinf:- ,blondie ' gonna love you too blondie\atomic\ - ' gonna love you too ogg figure an extract from file the bnf is shown in figure it defines as the literal text #extm followed by newline and then one or more entrys each entry consists of an info followed by newline then filename followed by newline an info starts with the literal text #extinffollowed by the duration specified by secondsthen commaand then the title the seconds is defined as an optional minus sign followed by one or more digits both the title and filename are loosely defined as sequences of any characters except newlines ::'#extm \nentryentry ::info '\nfilename '\ninfo ::'#extinf:seconds ',title seconds ::'-'\dtitle ::[^\ ]filename ::[^\ ]figure bnf for the format named tuples before reviewing the parser itselfwe will first look at the named tuple that we will use to store each resultsong collections namedtuple("song""title seconds filename"this is much more convenient than using dictionary with keys like "file ""title "and so onand where we have to write code to match up all those keys that end in the same number we will review the parser' code in four very short parts for ease of explanation if fh readline(!"#extm \ "print("this is not file"return [songs [info_re re compile( "#extinf:(? -?\ +),(? +)"