Skip to content

Commit 062f619

Browse files
authored
Merge pull request #114 from eddyb/parser-api
Introduce a less fragile Parser API.
2 parents 002ccf0 + 4fa49d8 commit 062f619

File tree

4 files changed

+191
-109
lines changed

4 files changed

+191
-109
lines changed

macros/tests/basic.rs

+7
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,11 @@ testcases![
176176
A("abab") => "1:1-1:5",
177177
A("aba") => "1:1-1:4",
178178
A("b") => r#"1:1: error: expected ["a"]"#;
179+
180+
nested_or {
181+
A = x:"x" { a:"a" | b:"b" };
182+
}:
183+
// FIXME(eddyb) figure out why the output is not `... => A {...}`.
184+
A("xa") => "\
185+
1:1-1:3 => ";
179186
];

src/generate/rust.rs

+18-30
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,7 @@ impl Continuation<'_> {
470470
fn to_inline(&mut self) -> &mut Src {
471471
if let Code::Label(ref label) = self.code {
472472
self.code = Code::Inline(quote!(
473-
c.code = #label;
474-
p.threads.spawn(c, _range);
473+
p.spawn(#label);
475474
));
476475
}
477476

@@ -584,7 +583,8 @@ macro_rules! thunk {
584583
}
585584

586585
fn pop_saved<F: ContFn>(f: impl FnOnce(Src) -> Thunk<F>) -> Thunk<impl ContFn> {
587-
f(quote!(c.saved.unwrap()))
586+
thunk!(let saved = p.take_saved();)
587+
+ f(quote!(saved))
588588
+ Thunk::new(|mut cont| {
589589
if let Some(&None) = cont.nested_frames.last() {
590590
*cont.nested_frames.last_mut().unwrap() =
@@ -599,8 +599,8 @@ fn pop_saved<F: ContFn>(f: impl FnOnce(Src) -> Thunk<F>) -> Thunk<impl ContFn> {
599599
})
600600
}
601601

602-
fn push_saved(saved: Src) -> Thunk<impl ContFn> {
603-
thunk!(c.saved = Some(#saved);)
602+
fn push_saved(parse_node_kind: ParseNodeKind) -> Thunk<impl ContFn> {
603+
thunk!(p.save(#parse_node_kind);)
604604
+ Thunk::new(move |mut cont| {
605605
if let Some((ret_label, outer_fn_label)) = cont.nested_frames.pop().unwrap() {
606606
let inner_fn_label = mem::replace(cont.fn_code_label, outer_fn_label);
@@ -627,15 +627,14 @@ fn call(callee: Rc<CodeLabel>) -> Thunk<impl ContFn> {
627627
Thunk::new(move |mut cont| {
628628
let label = cont.to_label().clone();
629629
cont.code = Code::Inline(quote!(
630-
c.code = #label;
631-
p.call(Call { callee: #callee, range: _range }, c);
630+
p.call(#callee, #label);
632631
));
633632
cont
634633
})
635634
}
636635

637636
fn ret() -> Thunk<impl ContFn> {
638-
thunk!(p.ret(c, _range);)
637+
thunk!(p.ret();)
639638
+ Thunk::new(|mut cont| {
640639
assert!(cont.to_inline().is_empty());
641640
cont
@@ -749,7 +748,7 @@ fn reify_as(label: Rc<CodeLabel>) -> Thunk<impl ContFn> {
749748
}
750749

751750
fn forest_add_choice(parse_node_kind: &ParseNodeKind, choice: ParseNodeKind) -> Thunk<impl ContFn> {
752-
thunk!(p.forest_add_choice(#parse_node_kind, c.fn_input.subtract_suffix(_range), #choice);)
751+
thunk!(p.forest_add_choice(#parse_node_kind, #choice);)
753752
}
754753

755754
fn concat_and_forest_add(
@@ -758,18 +757,12 @@ fn concat_and_forest_add(
758757
right: Thunk<impl ContFn>,
759758
parse_node_kind: ParseNodeKind,
760759
) -> Thunk<impl ContFn> {
761-
thunk!(assert_eq!(_range.start(), c.fn_input.start());)
762-
+ left
763-
+ push_saved(quote!(ParseNode {
764-
kind: #left_parse_node_kind,
765-
range: c.fn_input.subtract_suffix(_range),
766-
}))
760+
left + push_saved(left_parse_node_kind)
767761
+ right
768762
+ pop_saved(move |saved| {
769763
thunk!(p.forest_add_split(
770764
#parse_node_kind,
771-
c.fn_input.subtract_suffix(_range),
772-
#saved.range.len(),
765+
#saved,
773766
);)
774767
})
775768
}
@@ -799,7 +792,7 @@ impl<Pat: Ord + Hash + RustInputPat> RuleGenerateMethods<Pat> for Rule<Pat> {
799792
(Rule::Empty, _) => cont,
800793
(Rule::Eat(pat), _) => {
801794
let pat = pat.rust_matcher();
802-
check(quote!(let Some(_range) = p.input_consume_left(_range, &(#pat)))).apply(cont)
795+
check(quote!(let Some(mut p) = p.input_consume_left(&(#pat)))).apply(cont)
803796
}
804797
(Rule::Call(r), _) => call(Rc::new(CodeLabel::NamedRule(r.clone()))).apply(cont),
805798
(Rule::Concat([left, right]), None) => {
@@ -817,12 +810,11 @@ impl<Pat: Ord + Hash + RustInputPat> RuleGenerateMethods<Pat> for Rule<Pat> {
817810
))
818811
.apply(cont),
819812
(Rule::Or(cases), Some((rc_self, rules))) => {
820-
(thunk!(assert_eq!(_range.start(), c.fn_input.start());)
821-
+ parallel(ThunkIter(cases.iter().map(|rule| {
822-
let parse_node_kind = rule.parse_node_kind(rules);
823-
rule.generate_parse(Some((rule, rules)))
824-
+ forest_add_choice(&rc_self.parse_node_kind(rules), parse_node_kind)
825-
}))))
813+
(parallel(ThunkIter(cases.iter().map(|rule| {
814+
let parse_node_kind = rule.parse_node_kind(rules);
815+
rule.generate_parse(Some((rule, rules)))
816+
+ forest_add_choice(&rc_self.parse_node_kind(rules), parse_node_kind)
817+
}))))
826818
.apply(cont)
827819
}
828820
(Rule::Opt(rule), _) => {
@@ -1395,12 +1387,8 @@ where
13951387
quote!(impl<I> gll::runtime::CodeStep<I> for _C
13961388
where I: gll::runtime::Input<Slice = #rust_slice_ty>,
13971389
{
1398-
fn step<'i>(
1399-
p: &mut gll::runtime::Parser<'i, _C, I>,
1400-
mut c: gll::runtime::Continuation<'i, _C>,
1401-
_range: gll::runtime::Range<'i>,
1402-
) {
1403-
match c.code {
1390+
fn step<'i>(self, mut p: gll::runtime::Parser<'_, 'i, _C, I>) {
1391+
match self {
14041392
#(#code_label_arms)*
14051393
}
14061394
}

src/generate/templates/imports.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use gll::runtime::{
2-
nd::Arrow, traverse, Call, CodeLabel, Continuation, ParseNode, ParseNodeKind, ParseNodeShape,
3-
Range,
2+
nd::Arrow, traverse, CodeLabel, ParseNode, ParseNodeKind, ParseNodeShape, Range,
43
};
54
use std::any;
65
use std::fmt;

0 commit comments

Comments
 (0)