Crates.io | gll-pg-macros |
lib.rs | gll-pg-macros |
version | 0.5.0 |
source | src |
created_at | 2019-11-12 15:21:13.376513 |
updated_at | 2023-11-10 16:41:40.551177 |
description | A parser generator for GLL grammar, macros part |
homepage | |
repository | https://github.com/jiegec/gll-pg |
max_upload_size | |
id | 180676 |
size | 46,077 |
A Parser Generator for GLL parser. It uses Logos as lexer.
Add to Cargo.toml:
[dependencies]
gll-pg-macros = "0.2"
gll-pg-core = "0.2"
logos = "0.9"
Write a lexer using Logos:
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:
struct Parser {}
#[gll(S, Token)]
impl Parser {
#[rule(S -> S Ta)]
fn s1(s: &usize, _a: &LogosToken<Token>) -> usize {
*s + 1
}
#[rule(S ->)]
fn s2() -> usize {
0
}
}
Run it:
let mut lexer = Token::lexer("aaa");
let mut parser = Parser {};
let res = parser.parse(&mut lexer).unwrap();
// res is a StreamingIterator
let vec: Vec<usize> = res.cloned().collect();
assert_eq!(res, vec![3]);
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.
It can handle recursive grammars:
S -> a
S -> S S
S -> S S S
Code snippet:
#[gll(S, Token)]
impl Parser {
#[rule(S -> Ta)]
fn s1(_a: &LogosToken<Token>) -> 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.
MashPlant/lalr1
.