# Idea
A rust macro for generating PEG parsers.
# Features
- Literals
- strs `"Hello"`
- chars `'c'`
- char ranges `'0'..='9'`
- any character `any`
- Span `$e`
- Atomic `@e`
- Named `name: e`
- Lookahead
- Positive lookahead `&e`
- Negative lookahead `!e`
- Sequence `e e`
- Alternation `e | e`
- Number
- Many 0 (zero or more) `e*`
- Many 1 (one or more) `e+`
- Optional (zero or one) `e?`
# Predefined rules
```
any = // Matches any single character
digit = '0'..='9'
alpha = insensitive['a'..='z']
space = (whitespace | comment)*
```
# Grammar
```
rule = name '=' alt
named = name ':' unary
unary = prefix | postfix | atom
prefix_op
= '$' // Span
| '@' // Atomic
| '!' // Negative lookahead
| '&' // Positive lookahead
postfix_op
= '*' // Many0
| '+' // Many1
| '?' // Optional
prefix = prefix_op atom
postfix = postfix_op atom
atom = name | literal | parenthesized
parenthesized = '(' alt ')'
```
# Left-Recursion
## Detection
## Runtime
Try the rule over and over, with recursion depth from 1.., until the parse fails. Now the latest cached result is the answer.
# Compilation
- Parse the syntax
- Replace all rule names with indices
- Detect overwriting of built-in rules
- Mark left-recursive rules
- Report refutable bindings
# Delim
For delimiters, we may want to select for
- 0 or more occurrences `[]`
- 1 or more occurrences `[1]`
- 1 or more occurrences, but only when there is a trailing comma `[1,]`
- When `x` has return type `X` and `y` has return type `Y`, `x ^ y` should have return type `(Vec<X>, Vec<Y>)`
- Tuple can be made as follows:
```
tuple = '(' item: item ',' items: item ^ ',' ')' {
let mut items = items.0;
items.insert(0, item);
items
}
```
Alternatively (this isn't possible yet)
```
tuple = '(' items: item ^ ',' ')' {?
// At least one comma
match items.1.len() {
0 => None
_ => Some(items.0)
}
}
```
# Todo