Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jiegec/gll-pg
A GLL parser generator, inspired by MashPlant/lalr1.
https://github.com/jiegec/gll-pg
parser-generator rust rust-macro
Last synced: 2 months ago
JSON representation
A GLL parser generator, inspired by MashPlant/lalr1.
- Host: GitHub
- URL: https://github.com/jiegec/gll-pg
- Owner: jiegec
- License: mit
- Created: 2019-11-12T08:47:20.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2023-11-11T15:28:52.000Z (about 1 year ago)
- Last Synced: 2024-04-28T23:04:17.126Z (9 months ago)
- Topics: parser-generator, rust, rust-macro
- Language: Rust
- Homepage:
- Size: 86.9 KB
- Stars: 6
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# gll-pg
A Parser Generator for GLL parser. It uses Logos as lexer.
## Usage
Add to Cargo.toml:
```toml
[dependencies]
gll-pg-macros = "0.2"
gll-pg-core = "0.2"
logos = "0.9"
```Write a lexer using Logos:
```rust
use logos::Logos;#[derive(Logos, Debug, Eq, PartialEq, Clone)]
pub enum Token {
End, // must not change this
#[error]
Error,
#[token(" ")]
_Eps, // must not change this, will be skipped
#[token("a")]
Ta,
}
```Use gll-pg to generate parser:
```rust
struct Parser {}#[gll(S, Token)]
impl Parser {
#[rule(S -> S Ta)]
fn s1(s: &usize, _a: &LogosToken) -> usize {
*s + 1
}
#[rule(S ->)]
fn s2() -> usize {
0
}
}
```Run it:
```rust
let mut lexer = Token::lexer("aaa");
let mut parser = Parser {};
let res = parser.parse(&mut lexer).unwrap();
// res is a StreamingIterator
let vec: Vec = res.cloned().collect();
assert_eq!(res, vec![3]);
```## Example
### Ambiguous Calculator
For the grammar below:
```
E -> E + E
E -> E * E
E -> - E
E -> ( E )
E -> int
```For input "1 + 2 \* 3", it gives [7, 9].
For input "1 + (2 \* -3)", it gives [-5].See `tests/src/arith.rs` for detail.
### Recursive
It can handle recursive grammars:
```
S -> a
S -> S S
S -> S S S
```Code snippet:
```rust
#[gll(S, Token)]
impl Parser {
#[rule(S -> Ta)]
fn s1(_a: &LogosToken) -> usize {
1
}
#[rule(S -> S S)]
fn s2(s1: &usize, s2: &usize) -> usize {
s1 + s2
}
#[rule(S -> S S S)]
fn s3(s1: &usize, s2: &usize, s3: &usize) -> usize {
s1 + s2 + s3
}
}// "" gives []
// "a" gives [1]
// "aa" gives [2]
// "aaa" gives [3,3,3]
// "aaaa" gives [4, 4, 4, 4, 4, 4, 4, 4, 4]
```See `tests/src/crazy.rs` for detail.
## Changelog
### Release 0.4.0 2021-01-17
1. Migrate to Logos v0.11.
### Release 0.3.0 2019-11-15
1. Return a struct that impls StreamingIterator to give derivations lazily.
2. Implement memoization for shared structure of derivations.
3. Turn all clone calls to reference to arena objects.
4. Implement diagnostics to catch type mismatch errors.
5. Make errors in user code reported with correct line numbers.### Release 0.2.1 2019-11-13
1. Improve documentation.
### Release 0.2.0 2019-11-13
1. Allow access to struct fields.
### Release 0.1.0 2019-11-12
1. Initial working version.
2. The parser recursively clone & collect all possible derivations.## References
1. Code generation and template is learned from `MashPlant/lalr1`.
2. Scott, E., & Johnstone, A. (2010). GLL parsing. Electronic Notes in Theoretical Computer Science, 253(7), 177-189.
3. Scott, E., & Johnstone, A. (2013). GLL parse-tree generation. Science of Computer Programming, 78(10), 1828-1844.