Exercise 1: Adding a Bare BANG Token — Possible Solution ==================================================================== THE FIX ------------------------------ single_char_map = { '+': 'PLUS', '-': 'MINUS', '*': 'STAR', '/': 'SLASH', '=': 'EQUAL', '<': 'LESS', '>': 'GREATER', '!': 'BANG', '(': 'LPAREN', ')': 'RPAREN', '{': 'LBRACE', '}': 'RBRACE', ';': 'SEMICOLON', ',': 'COMMA', '.': 'DOT', } Adding '!': 'BANG' to the existing single-character map - the two-character check for '!=' already runs BEFORE this fallback map is consulted, so it doesn't need any changes. RESULTS ------------------------------ '!found': [BANG('!'), IDENTIFIER('found')] 'a != b': [IDENTIFIER('a'), !=('!='), IDENTIFIER('b')] A bare '!' now tokenizes correctly as its own BANG token, and the existing '!=' handling is completely unaffected. WHY THIS WORKS AS AN ANSWER ------------------------------ This confirms the maximal-munch ordering in the chapter's own lexer already does the right thing here without needing any reordering: the two-character lookahead check for '!=' runs first, and only falls through to the single-character map when the two-character check doesn't match. Adding a new single-character token is safe precisely because that ordering is already correct - a genuinely different situation from the chapter's own maximal-munch finding, where the BUG was checking single characters FIRST. Here, the two-character check was already first, so extending the single-character fallback list is a purely additive, risk-free change.