prism_parser/parser/
parser_rule.rs

1use crate::core::adaptive::{GrammarState, RuleId, RuleState};
2use crate::core::context::ParserContext;
3use crate::core::parser::Parser;
4use crate::core::pos::Pos;
5use crate::core::state::ParserState;
6use crate::error::error_printer::ErrorLabel;
7use crate::error::ParseError;
8use crate::grammar::action_result::ActionResult;
9use crate::parser::parser_rule_body::parser_body_cache_recurse;
10use crate::parser::var_map::{VarMap, VarMapValue};
11
12pub fn parser_rule<'a, 'arn: 'a, 'grm: 'arn, E: ParseError<L = ErrorLabel<'grm>> + 'grm>(
13    rules: &'arn GrammarState<'arn, 'grm>,
14    rule: RuleId,
15    args: &'a [VarMapValue<'arn, 'grm>],
16) -> impl Parser<'arn, 'grm, &'arn ActionResult<'arn, 'grm>, E> + 'a {
17    move |pos: Pos, state: &mut ParserState<'arn, 'grm, E>, context: ParserContext| {
18        let rule_state: &'arn RuleState<'arn, 'grm> = rules
19            .get(rule)
20            .unwrap_or_else(|| panic!("Rule not found: {rule}"));
21
22        assert_eq!(rule_state.args.len(), args.len());
23        let rule_args = VarMap::from_iter(
24            rule_state.args.iter().cloned().zip(args.iter().cloned()),
25            state.alloc,
26        );
27
28        let mut res = parser_body_cache_recurse(rules, (rule_state.blocks, rule_args))
29            .parse(pos, state, context);
30        res.add_label_implicit(ErrorLabel::Debug(
31            pos.span_to(res.end_pos()),
32            rule_state.name,
33        ));
34        res.map(|pr| pr)
35    }
36}