Skip to content

Commit

Permalink
Cleanup parser_cache_recurse
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanBrouwer committed Mar 24, 2024
1 parent c20e98c commit de67c88
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 30 deletions.
2 changes: 1 addition & 1 deletion prism-compiler/src/coc/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl Env {
pub fn len(&self) -> usize {
self.0.len()
}

pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
Expand Down
4 changes: 2 additions & 2 deletions prism-compiler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::coc::{TcEnv};
use crate::coc::TcEnv;
use lazy_static::lazy_static;
use prism_parser::error::error_printer::print_set_error;
use prism_parser::grammar::GrammarFile;
use prism_parser::parse_grammar;
use prism_parser::parser::parser_instance::{run_parser_rule};
use prism_parser::parser::parser_instance::run_parser_rule;
use prism_parser::rule_action::RuleAction;

pub mod coc;
Expand Down
39 changes: 18 additions & 21 deletions prism-parser/src/core/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,20 @@ impl<'grm, 'arn, E: ParseError> ParserCache<'grm, 'arn, E> {

pub fn parser_cache_recurse<'a, 'arn: 'a, 'grm: 'arn, E: ParseError<L = ErrorLabel<'grm>>>(
sub: &'a impl Parser<'arn, 'grm, &'arn ActionResult<'arn, 'grm>, E>,
id: (
ByAddress<&'arn [BlockState<'arn, 'grm>]>,
ParserContext,
GrammarStateId,
Vec<(&'grm str, RuleId)>,
),
block: ByAddress<&'arn [BlockState<'arn, 'grm>]>,
state: GrammarStateId,
params: Vec<(&'grm str, RuleId)>,
) -> impl Parser<'arn, 'grm, &'arn ActionResult<'arn, 'grm>, E> + 'a {
move |pos_start: Pos, state: &mut PCache<'arn, 'grm, E>, context: &ParserContext| {
move |pos_start: Pos, cache: &mut PCache<'arn, 'grm, E>, context: &ParserContext| {
//Check if this result is cached
let key = CacheKey {
pos: pos_start,
block: id.0,
ctx: id.1.clone(),
state: id.2,
params: id.3.clone(),
block,
ctx: context.clone(),
state,
params: params.clone(),
};
if let Some(cached) = state.cache_get(&key) {
if let Some(cached) = cache.cache_get(&key) {
return cached.clone();
}

Expand All @@ -140,8 +137,8 @@ pub fn parser_cache_recurse<'a, 'arn: 'a, 'grm: 'arn, E: ParseError<L = ErrorLab
let mut res_recursive = PResult::new_err(E::new(pos_start.span_to(pos_start)), pos_start);
res_recursive.add_label_explicit(Debug(pos_start.span_to(pos_start), "LEFTREC"));

let cache_state = state.cache_state_get();
state.cache_insert(key.clone(), res_recursive);
let cache_state = cache.cache_state_get();
cache.cache_insert(key.clone(), res_recursive);

//Now execute the grammar rule, taking into account left recursion
//The way this is done is heavily inspired by http://web.cs.ucla.edu/~todd/research/pepm08.pdf
Expand All @@ -150,24 +147,24 @@ pub fn parser_cache_recurse<'a, 'arn: 'a, 'grm: 'arn, E: ParseError<L = ErrorLab
//- Try to parse the current (rule, position). If this fails, there is definitely no left recursion. Otherwise, we now have a seed.
//- Put the new seed in the cache, and rerun on the current (rule, position). Make sure to revert the cache to the previous state.
//- At some point, the above will fail. Either because no new input is parsed, or because the entire parse now failed. At this point, we have reached the maximum size.
let res = sub.parse(pos_start, state, context);
let res = sub.parse(pos_start, cache, context);
match res {
POk(mut o, mut spos, mut epos, mut empty, mut be) => {
//Did our rule left-recurse? (Safety: We just inserted it)
if !state.cache_is_read(key.clone()).unwrap() {
if !cache.cache_is_read(key.clone()).unwrap() {
//No leftrec, cache and return
let res = POk(o, spos, epos, empty, be);
state.cache_insert(key, res.clone());
cache.cache_insert(key, res.clone());
res
} else {
//There was leftrec, we need to grow the seed
loop {
//Insert the current seed into the cache
state.cache_state_revert(cache_state);
state.cache_insert(key.clone(), POk(o, spos, epos, empty, be.clone()));
cache.cache_state_revert(cache_state);
cache.cache_insert(key.clone(), POk(o, spos, epos, empty, be.clone()));

//Grow the seed
let new_res = sub.parse(pos_start, state, context);
let new_res = sub.parse(pos_start, cache, context);
match new_res {
POk(new_o, new_spos, new_epos, new_empty, new_be)
if new_epos.cmp(&epos).is_gt() =>
Expand Down Expand Up @@ -195,7 +192,7 @@ pub fn parser_cache_recurse<'a, 'arn: 'a, 'grm: 'arn, E: ParseError<L = ErrorLab
}
}
res @ PErr(_, _) => {
state.cache_insert(key, res.clone());
cache.cache_insert(key, res.clone());
res
}
}
Expand Down
9 changes: 3 additions & 6 deletions prism-parser/src/parser/parser_rule_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,9 @@ pub fn parser_body_cache_recurse<
move |stream: Pos, cache: &mut PCache<'arn, 'grm, E>, context: &ParserContext| {
parser_cache_recurse(
&parser_body_sub_blocks(rules, bs, rule_args),
(
ByAddress(bs),
context.clone(),
rules.unique_id(),
rule_args.to_vec(),
),
ByAddress(bs),
rules.unique_id(),
rule_args.to_vec(),
)
.parse(stream, cache, context)
}
Expand Down

0 comments on commit de67c88

Please sign in to comment.