# Part 2: The Parser

Andy Balaam
artificialworlds.net/blog

# Recap - Lexing

`foo = "bar";`

becomes:

```("symbol", "foo") ("=" , "" ) ("string", "bar") (";" , "" ) ```

# Recap - Lexing

`print( x + 2 );`

becomes:

```("symbol" , "print") ("(" , "" ) ("symbol" , "x" ) ("operator", "+" ) ("number" , "2" ) (")" , "" ) (";" , "" ) ```

# Parsing

`x = 3 + 4;`

becomes:

```Assignment: Symbol: x Value: Operation: Type: + Arguments: 3 4 ```

# Parsing

`print( x + 2 );`

becomes:

```FunctionCall: Function: print Arguments: Operation: Type: + Arguments: x 2 ```

# Parsing

`print( x + 2 );`

becomes:

```("call", ("symbol", "print"), [ ("operation", "+", ("symbol", "x"), ("number", "2") ) ] ) ```

Cell has four expression types:

• Assignment x = 3
• Operations 4 + y
• Function calls sqrt( -1 )
• Function definitions {:(x, y) x*x + y*y;}

The coolest thing about Cell is:

• if is a function, not a keyword

More at: github.com/andybalaam/cell

• if is a function, not a keyword
```if( is_even( 2 ), { print "Even!"; }, { print "Odd."; } ); ```

More at: github.com/andybalaam/cell

# Cell's parser

```def parse(tokens): parser = Parser(tokens, ";") while parser.tokens.next is not None: p = parser.next_expr(None) if p is not None: yield p parser.tokens.move_next() ```

# Cell's parser

```class Parser: def __init__(self, tokens, stop_at): self.tokens = tokens self.stop_at = stop_at ```

# Cell's parser

```def next_expr(self, prev): self.fail_if_at_end(";") typ, value = self.tokens.next if typ in self.stop_at: return prev self.tokens.move_next() # ... ```

# Cell's parser

```def next_expr(self, prev): # ... if prev is None and typ in (# ... elif typ == "operation": # ... elif typ == "(": # ... elif typ == "{": # ... elif typ == "=": # ... else: # ... ```

# Cell's parser

```def next_expr(self, prev): # ... if prev is None and typ in ( "number", "string", "symbol"): return self.next_expr((typ, value)) elif typ == "operation": # ... elif typ == "(": # ... elif typ == "{": # ... elif typ == "=": # ... else: # ... ```

# Cell's parser

```def next_expr(self, prev): # ... if prev is None and typ in (... elif typ == "operation": nxt = self.next_expr(None) return self.next_expr( ("operation", value, prev, nxt)) elif typ == "(": # ... elif typ == "{": # ... elif typ == "=": # ... else: # ... ```

# Cell's parser

```def next_expr(self, prev): # ... if prev is None and typ in (... elif typ == "operation": # ... elif typ == "(": args = self.multi_exprs(",", ")") return self.next_expr(("call", prev, args)) elif typ == "{": # ... elif typ == "=": # ... else: # ... ```

# Cell's parser

```def multi_exprs(self, sep, end): ret = [] self.fail_if_at_end(end) typ = self.tokens.next[0] if typ == end: self.tokens.move_next() else: # ... return ret ```

# Cell's parser

```def multi_exprs(self, sep, end): # ... else: arg_parser = Parser(self.tokens, (sep, end)) while typ != end: p = arg_parser.next_expr(None) if p is not None: ret.append(p) typ = self.tokens.next[0] self.tokens.move_next() self.fail_if_at_end(end) return ret ```

# Cell's parser

```def next_expr(self, prev): # ... elif typ == "(": # ... elif typ == "{": params = self.parameters_list() body = self.multi_exprs(";", "}") return self.next_expr(("function", params, body)) elif typ == "=": # ... else: # ... ```

# Cell's parser

```def next_expr(self, prev): # ... elif typ == "(": # ... elif typ == "{": # ... elif typ == "=": if prev[0] != "symbol": raise Exception(...) nxt = self.next_expr(None) return self.next_expr(("assignment", prev, nxt)) else: # ... ```

# Cell's parser

```def next_expr(self, prev): # ... elif typ == "(": # ... elif typ == "{": # ... elif typ == "=": # ... else: raise Exception("Unexpected token: " ... ```

# Donate

Donate! patreon.com/andybalaam

# Play

Play! artificialworlds.net/rabbit-escape