Introduction
Imagine trying to understand a sentence by breaking it down into smaller parts step by step. Recursive descent parsing solves the problem of analyzing complex sentences or code by breaking them into manageable pieces using simple rules.
Imagine assembling a toy model by following instructions step by step. Each step may involve smaller steps, and if a step doesn't fit, you go back and try a different approach. This way, you build the whole model from big parts to small details.
┌───────────────┐
│ Start (Rule) │
└──────┬────────┘
│ calls
▼
┌───────────────┐
│ Sub-rule A │
└──────┬────────┘
│ calls
▼
┌───────────────┐
│ Sub-rule B │
└──────┬────────┘
│ matches input
▼
[Input tokens]
If match fails, backtrack to try other rules.class Parser: def __init__(self, tokens): self.tokens = tokens self.pos = 0 def parse_expression(self): # expression -> term ('+' term)* node = self.parse_term() while self.match('+'): right = self.parse_term() node = ('+', node, right) return node def parse_term(self): # term -> number if self.pos < len(self.tokens) and self.tokens[self.pos].isdigit(): val = self.tokens[self.pos] self.pos += 1 return ('num', val) raise Exception('Expected number') def match(self, char): if self.pos < len(self.tokens) and self.tokens[self.pos] == char: self.pos += 1 return True return False # Example usage: parser = Parser(['3', '+', '4', '+', '5']) ast = parser.parse_expression() print(ast)
recursive descent parsing?Expr -> 'a' Expr | 'b'aaab?Pass the test and this pattern moves unknown