rust 52 lines · 8 steps

How a tokenizer turns text into tokens

A peekable character iterator scans arithmetic input and emits a typed token stream, failing cleanly on bad input.

Explained by highlit
1#[derive(Debug, Clone, PartialEq)]
2pub enum Token {
3 Number(f64),
4 Plus,
5 Minus,
6 Star,
7 Slash,
8 LParen,
9 RParen,
10}
11 
12pub fn tokenize(input: &str) -> Result<Vec<Token>, String> {
13 let mut tokens = Vec::new();
14 let mut chars = input.chars().peekable();
15 
16 while let Some(&c) = chars.peek() {
17 match c {
18 ' ' | '\t' | '\n' | '\r' => {
19 chars.next();
20 }
21 '+' => { chars.next(); tokens.push(Token::Plus); }
22 '-' => { chars.next(); tokens.push(Token::Minus); }
23 '*' => { chars.next(); tokens.push(Token::Star); }
24 '/' => { chars.next(); tokens.push(Token::Slash); }
25 '(' => { chars.next(); tokens.push(Token::LParen); }
26 ')' => { chars.next(); tokens.push(Token::RParen); }
27 '0'..='9' | '.' => {
28 let mut literal = String::new();
29 let mut seen_dot = false;
30 while let Some(&d) = chars.peek() {
31 if d.is_ascii_digit() {
32 literal.push(d);
33 chars.next();
34 } else if d == '.' && !seen_dot {
35 seen_dot = true;
36 literal.push(d);
37 chars.next();
38 } else {
39 break;
40 }
41 }
42 let value = literal
43 .parse::<f64>()
44 .map_err(|_| format!("invalid number: {literal}"))?;
45 tokens.push(Token::Number(value));
46 }
47 other => return Err(format!("unexpected character: {other:?}")),
48 }
49 }
50 
51 Ok(tokens)
52}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Peeking before consuming lets a scanner decide what a character means without losing it.
  2. 2Modeling tokens as a typed enum makes downstream parsing exhaustive and safe.
  3. 3Returning a Result at the tokenizer boundary surfaces malformed input early with context.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How a tokenizer turns text into tokens — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code