Skip to content

Commit e95500c

Browse files
committed
move precedence into SuccessfulParse
We are going to need access to it when we recurse. Besides, the code looks cleaner this way!
1 parent 606a240 commit e95500c

File tree

2 files changed

+23
-32
lines changed

2 files changed

+23
-32
lines changed

crates/formality-core/src/parse.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub trait CoreParse<L: Language>: Sized + Debug + Clone + Eq + 'static {
2424
}
2525

2626
mod parser;
27-
pub use parser::{skip_whitespace, ActiveVariant, Parser};
27+
pub use parser::{skip_whitespace, ActiveVariant, Parser, Precedence};
2828

2929
/// Parses `text` as a term with the given bindings in scope.
3030
///
@@ -76,21 +76,15 @@ pub struct SuccessfulParse<'t, T> {
7676
/// reduction.
7777
reductions: Vec<&'static str>,
7878

79+
/// The precedence of this parse, which is derived from the value given
80+
/// to `parse_variant`.
81+
precedence: Precedence,
82+
7983
/// The value produced.
8084
value: T,
8185
}
8286

8387
impl<'t, T> SuccessfulParse<'t, T> {
84-
#[track_caller]
85-
pub fn new(text: &'t str, reductions: Vec<&'static str>, value: T) -> Self {
86-
// assert!(!reductions.is_empty());
87-
Self {
88-
text,
89-
reductions,
90-
value,
91-
}
92-
}
93-
9488
/// Extract the value parsed and the remaining text,
9589
/// ignoring the reductions.
9690
pub fn finish(self) -> (T, &'t str) {
@@ -103,6 +97,7 @@ impl<'t, T> SuccessfulParse<'t, T> {
10397
SuccessfulParse {
10498
text: self.text,
10599
reductions: self.reductions,
100+
precedence: self.precedence,
106101
value: op(self.value),
107102
}
108103
}
@@ -117,6 +112,7 @@ where
117112
SuccessfulParse {
118113
text: term.text,
119114
reductions: term.reductions,
115+
precedence: term.precedence,
120116
value: term.value.upcast(),
121117
}
122118
}

crates/formality-core/src/parse/parser.rs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ where
3030
scope: &'s Scope<L>,
3131
start_text: &'t str,
3232
nonterminal_name: &'static str,
33-
successes: Vec<(SuccessfulParse<'t, T>, Precedence)>,
33+
successes: Vec<SuccessfulParse<'t, T>>,
3434
failures: Set<ParseError<'t>>,
3535
}
3636

37-
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
38-
struct Precedence(usize);
37+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
38+
pub struct Precedence(usize);
3939

4040
/// The "active variant" struct is the main struct
4141
/// you will use if you are writing custom parsing logic.
@@ -152,6 +152,8 @@ where
152152
);
153153
let guard = span.enter();
154154

155+
let variant_precedence = Precedence(variant_precedence);
156+
155157
let mut active_variant = ActiveVariant {
156158
scope: self.scope,
157159
text: self.start_text,
@@ -172,14 +174,12 @@ where
172174
active_variant.reductions.push(variant_name);
173175
}
174176

175-
self.successes.push((
176-
SuccessfulParse {
177-
text: active_variant.text,
178-
reductions: active_variant.reductions,
179-
value,
180-
},
181-
Precedence(variant_precedence),
182-
));
177+
self.successes.push(SuccessfulParse {
178+
text: active_variant.text,
179+
reductions: active_variant.reductions,
180+
precedence: variant_precedence,
181+
value,
182+
});
183183
tracing::trace!("success: {:?}", self.successes.last().unwrap());
184184
}
185185

@@ -242,7 +242,7 @@ where
242242
.zip(0..)
243243
.all(|(s_j, j)| i == j || Self::is_preferable(s_i, s_j))
244244
{
245-
let (s_i, _) = self.successes.into_iter().skip(i).next().unwrap();
245+
let s_i = self.successes.into_iter().skip(i).next().unwrap();
246246
// It's better to print this result alongside the main parsing section.
247247
drop(guard);
248248
tracing::trace!("best parse = `{:?}`", s_i);
@@ -257,19 +257,13 @@ where
257257
);
258258
}
259259

260-
fn is_preferable(
261-
s_i: &(SuccessfulParse<T>, Precedence),
262-
s_j: &(SuccessfulParse<T>, Precedence),
263-
) -> bool {
264-
let (parse_i, prec_i) = s_i;
265-
let (parse_j, prec_j) = s_j;
266-
260+
fn is_preferable(s_i: &SuccessfulParse<T>, s_j: &SuccessfulParse<T>) -> bool {
267261
fn has_prefix<T: Eq>(l1: &[T], l2: &[T]) -> bool {
268262
l1.len() > l2.len() && (0..l2.len()).all(|i| l1[i] == l2[i])
269263
}
270264

271-
prec_i > prec_j
272-
|| (prec_i == prec_j && has_prefix(&parse_i.reductions, &parse_j.reductions))
265+
s_i.precedence > s_j.precedence
266+
|| (s_i.precedence == s_j.precedence && has_prefix(&s_i.reductions, &s_j.reductions))
273267
}
274268
}
275269

@@ -686,6 +680,7 @@ where
686680
let SuccessfulParse {
687681
text,
688682
reductions,
683+
precedence: _,
689684
value,
690685
} = op(self.scope, self.text)?;
691686

0 commit comments

Comments
 (0)