- Many tools exist to turn a grammar into a lexer/parser (ANTLR, Yacc, JavaCC)
-
Commonly consists of two parts:
1.
**Lexer:** groups characters into *tokens*
2.
**Parser:** uses grammar to produce parse tree
-
We could spend an entire course discussing the nuances of lexing and parsing...
-
Instead, we are going to focus entirely on how to actually *interpret* a parse tree
-
As a result, we are going to use a Haskell library to help us with parsing
![Box diagram for parser](https://upload.wikimedia.org/wikipedia/commons/d/d6/Parser_Flow%D5%B8.gif)
## Types of Parsers
- **Top-Down Parsers**
+ Aka "recursive descent parsers"
+
Start at the top-level and repeatedly apply rules until the target string is reached
+
LL parsers are in this category
-
**Bottom-Up Parsers**
+ Start with the target string and apply the rules in reverse to build up to the top-level rule
+
LR parsers are in this category
## Lookahead
- For efficiency, some parsers include a **lookahead**
+ The parser knows about future tokens as well as the current token when making decisions
-
This can help with efficiency for some grammars
-
You may see terms "LR(k) parser" which is an LR parser that uses a lookahead of k
# Monadic Parsing
## Monadic Parsers
- Monadic parsers are commonly used in functional programming languages
+ They are top-down parsers
-
These are commonly used for domain-specific languages rather than general-purpose languages
+
They are less efficient than their optimized LL counterparts
+
However, they are extremely easy to use!
## Hutton's Parser Monad
- We will be using Hutton's `Parser` monad covered a few weeks ago
```haskell
newtype Parser a = P { runParser :: String -> [(a,String)] }
```
-
Intuitively, a parser is a function from a `String` to some value of type `a`
-
Having a list of possible parsings allows us to handle errors and multiple possible parsings
## Hutton's Parser Monad
- Since `Parser a` is a monad, we can easily sequence parsers together
-
It also supports the `Alternative` typeclass:
```haskell
class Applicative m => Alternative m where
empty :: m a
(<|>) :: m a -> m a -> m a
```
## Using the Parser Monad
- Consider the following grammar for arithmetic:
```bnf