#125 · Parsing · Advanced · 115 XP · about 20 min
Before a program can work out rate * (hours + 1.5), it has to chop the text into tokens: names, numbers, operators and brackets. Write tokenize(source) that returns the tokens of source, in order, as a list of (kind, text) tuples:
'number': one or more digits, optionally followed by a . and one or more digits, like 42, 007 or 3.14.'name': a letter or underscore followed by any letters, digits or underscores, like rate, x2 or _total.'op': one of **, //, ==, !=, <=, >=, +, -, *, /, %, <, >, =. Always take the longest operator that fits, so ** is one token, not two.'paren': ( or ).Spaces and tabs separate tokens and are not returned. Any other character (including a ! that is not part of !=) is an error: raise a ValueError.
tokenize("rate * (hours + 1.5)") # returns [('name', 'rate'), ('op', '*'), ('paren', '('), ('name', 'hours'), # ('op', '+'), ('number', '1.5'), ('paren', ')')] tokenize("x**2>=y//3") # returns [('name', 'x'), ('op', '**'), ('number', '2'), ('op', '>='), # ('name', 'y'), ('op', '//'), ('number', '3')] tokenize("2x") # returns [('number', '2'), ('name', 'x')]
Tokens do not need spaces between them: 2x is a number followed by a name.
source has 0 to 10,000 ASCII characters.. only ever appears between two digits, as part of a number.Ready?
Accept the challenge to start writing. A small timer counts the time this page is in view.
Output appears here.