An open API service indexing awesome lists of open source software.

https://github.com/gtr/parsley

:herb: pratt parser for ivy in rust
https://github.com/gtr/parsley

Last synced: 5 months ago
JSON representation

:herb: pratt parser for ivy in rust

Awesome Lists containing this project

README

          

# parsley :herb:

Implementing the Pratt parsing algorithm in Rust. I decided to use the
following BNF grammar which is also the proposed new syntax for my programming
language, [Ivy](https://github.com/gtr/ivy).

```html
::= ';' ;

::= [ ]
| [ ]
| [x]
| [x]
| [x]
| [x]
| [ ]
| [x]
| [x]
| [x]
| [x]
| [x]
| [x]
| [ ]
| ; [x]

::= 'let'['mut']? [|] ['::']?'=';
::= 'mut' [ | ] '=' ;
::= | | ;
::= 'if' 'then' [ 'else' ]? ;
::= 'pub' [ | | | ] ;
::= 'data' [ ]? '(' ')' ;
::= | ;
::= 'package' ;
::= 'import' [ | ] ;
::= 'match' 'with' '(' [ ]* ')' ;
::= 'while' '{' [ ]* '}' ;
::= 'do' '{' [ ]* '}' ;
::= 'return' ;

::= 'fn' [ ':' ]? '=>' ;
::= 'fn' '::' ;
::= 'fn' [ ':' ]? '=>' ;

::= '(' [ [ ',' ]* ]? ')' ;
::= [ ':' ] ? ;

::= '<' [',' ]* '>' ; ;
::= [ '|' ]? [ '|' ]* ;
::= [ '::' ]? ;

::= 'struct' '(' ')' ;
::= 'struct' '(' ')' ;
::= [ ',' ]* [ ',' ]? ;
::= '::' ;

::= '|' '->'

::= [ '->' ]? ;
::= | '<' [ [ ',' ]* ] '>' ;
::= | '[' ']' ;
::= | '(' [ ',' ]* ')' ;
::= [ 'mut' ]? ;

::= [ '||' ]* ;
::= [ '&&' ]* ;
::= [ ( '==' | '!=' ) ]* ;
::= [ ( '>' | '>=' | '<' | '<=' ) ]* ;
::= [ ( '+' | '-' ) ]* ;
::= [ ( '*' | '/' ) ]* ;
::= ( '!' | '-' ) | ;

::= | ;
::= [ '.' ]* ;
::= [ '[' ']' ]* ;

::= '(' [ ]? ')'
|
|
| ;
::= '(' [ ',' ]* ')' ;

::= | ;
::= '[' [ ]? ']' ;
::= '[' '|' ']' ;
::= [ ',' ]* ;

::= '(' [ ',' ]* ')' ;
::= '(' [ ',' ]* [ ',' ]? ')' ;
::= '(' [ ',' ]* [ ',' ]? ')' ;

::=
|
| ;
```

## Example

The following Ivy code:

```haskell
fn factorial :: Int -> Int;
fn factorial (0) => 1;
fn factorial (n) => n * factorial(n - 1);
```

Is equivalent to the following vector of tokens:
```rust
// fn factorial :: Int -> Int;
new_token(TokenType::Fn),
new_token(TokenType::Symbol(format!("factorial"))),
new_token(TokenType::DoubleColon),
new_token(TokenType::Symbol(format!("Int"))),
new_token(TokenType::Arrow),
new_token(TokenType::Symbol(format!("Int"))),
new_token(TokenType::Semicolon),

// fn factorial (0) => 1;
new_token(TokenType::Fn),
new_token(TokenType::Symbol(format!("factorial"))),
new_token(TokenType::LParen),
new_token(TokenType::Integer(0)),
new_token(TokenType::RParen),
new_token(TokenType::EqArrow),
new_token(TokenType::Integer(1)),
new_token(TokenType::Semicolon),

// fn factorial (n) => n * factorial(n - 1);
new_token(TokenType::Fn),
new_token(TokenType::Symbol(format!("factorial"))),
new_token(TokenType::LParen),
new_token(TokenType::Symbol(format!("n"))),
new_token(TokenType::RParen),
new_token(TokenType::EqArrow),
new_token(TokenType::Symbol(format!("n"))),
new_token(TokenType::Star),
new_token(TokenType::Symbol(format!("factorial"))),
new_token(TokenType::LParen),
new_token(TokenType::Symbol(format!("n"))),
new_token(TokenType::Minus),
new_token(TokenType::Integer(1)),
new_token(TokenType::RParen),
new_token(TokenType::Semicolon),
```

And results in the following syntax tree:

```
[root]
0: [fn signature]
name: [Symbol 'factorial']
type: [->]
lhs: [Symbol 'Int']
rhs: [Symbol 'Int']
1: [fn declaration]
name: [Symbol 'factorial']
args: [Int '0']
value: [Int '1']
2: [fn declaration]
name: [Symbol 'factorial']
args: [Symbol 'n']
value: [*]
lhs: [Symbol 'n']
rhs: [call]
lhs: [Symbol 'factorial']
arg: [-]
lhs: [Symbol 'n']
rhs: [Int '1']
```