Crates.io | wop |
lib.rs | wop |
version | 0.1.0 |
source | src |
created_at | 2024-01-06 19:14:41.613367 |
updated_at | 2024-01-06 19:14:41.613367 |
description | An front-end to lrp |
homepage | |
repository | https://github.com/Defmc/lrp/tree/main/wop |
max_upload_size | |
id | 1091150 |
size | 101,581 |
lrp
parser libraryWriting direct grammars sucks: handling the lexer's input, creating tiny different rule productions, creating the reductor table and some other stuffs that we don't care about. This library is focused on simplifying this process, the only external thing you need is a lexer like logos
use my_crate::Ast;
use my_crate::Sym::*; // Each module should be imported separetely (there's no { } support yet)
// you can define alias for idents and string literals
alias Number = Number;
alias "+" = Add;
alias "(" = OpenParen;
alias ")" = CloseParen;
Add: Ast = Number:&n1 "+" Number:&n2 -> {
Ast::Add(n1, n2)
}%;
Expr: Ast = Add:&a -> {
/* Meta::new( */
Ast::Expr(a)/*,
Span::new(toks[0].item.span.start, toks.last().unwrap().item.span.end)
)*/
}%
| "(" Expr:&e ")" -> {
Ast::Expr(e)
}%;
EntryPoint: Ast = Expr:&e -> {
Ast::EntryPoint(e)
}%
Just use parse
or from_str
for Builder
and set the entry type (the tokens type):
let src = include_str!("your.grammar");
let builder1 = src.parse::<wop::Builder>();
let builder2 = wop::Builder::from_str(src);
assert_eq!(builder1, builder2);
To use it, just build it from Builder
and call builder.dump_grammar()
to generate the code for the grammar:
format!("let grammar = Grammar::new(Sym::EntryPoint, {}, Sym::Eof)", builder.dump_grammar(src)) // `src` is the source code for the grammar we used above
And for DFA building, remember to dump the reduct_map:
format!("parser.dfa(buf, {})", builder.dump_reduct_map(src))
Fun fact: This project uses itself.
Ideas:
Builder::dump_grammar
// should return a RuleMap
( x | y)
), the codeblock will be applied to both