Editor

Tokenize an Expression

#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.

Examples

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.

Constraints

  • source has 0 to 10,000 ASCII characters.
  • A . 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.