// This file was generated by Peginator v0.3.0
// Hash of the grammar file: 88B207768CE7546E36126BA6821C204DFAF2730CC1489CC8B4F1E8BB9938B362
// Any changes to it will be lost on regeneration

#[derive(Debug, Clone)]
pub struct PromptNode {
    pub part: Vec<PartNode>,
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone)]
pub enum PartNode {
    NumNode(NumNode),
    StrongNode(StrongNode),
    TotalNode(TotalNode),
    WeakNode(WeakNode),
    WordNode(WordNode),
}
#[derive(Debug, Clone)]
pub struct WordNode {
    pub id: Vec<IdentNode>,
    pub position: std::ops::Range<usize>,
}
#[derive(Debug, Clone)]
pub struct StrongNode {
    pub parts: Vec<PartNode>,
    pub num: Option<NumNode>,
    pub position: std::ops::Range<usize>,
}
#[derive(Debug, Clone)]
pub struct WeakNode {
    pub parts: Vec<PartNode>,
    pub num: Option<NumNode>,
    pub position: std::ops::Range<usize>,
}
#[derive(Debug, Clone)]
pub struct TotalNode {
    pub parts: Vec<PartNode>,
    pub position: std::ops::Range<usize>,
}
pub type Split = char;
pub type Times = char;
#[derive(Debug, Clone)]
pub struct NumNode {
    pub string: String,
    pub position: std::ops::Range<usize>,
}
#[derive(Debug, Clone)]
pub struct IdentNode {
    pub string: String,
    pub position: std::ops::Range<usize>,
}
pub type XID_CONTINUE = char;
impl peginator_generated::PegParser for PromptNode {
    fn parse_advanced<T: peginator_generated::ParseTracer>(
        s: &str,
        settings: &peginator_generated::ParseSettings,
    ) -> Result<Self, peginator_generated::ParseError> {
        Ok(peginator_generated::parse_PromptNode(
            peginator_generated::ParseState::new(s, settings),
            T::new(),
            &mut Default::default(),
        )?
        .result)
    }
}
#[allow(non_snake_case, unused_variables, unused_imports, unused_mut, dead_code)]
mod peginator_generated {
    use super::*;
    use peginator::runtime::*;
    pub use peginator::runtime::{IndentedTracer, ParseError, ParseSettings, ParseState, ParseTracer, PegParser, PegPosition};
    #[derive(Default)]
    pub struct ParseCache<'a> {
        _please_dont_complain: std::marker::PhantomData<&'a ()>,
    }
    mod PromptNode_impl {
        use super::*;
        mod part_0 {
            use super::*;
            mod closure {
                use super::*;
            }
            #[inline(always)]
            pub fn parse<'a>(
                state: ParseState<'a>,
                tracer: impl ParseTracer,
                cache: &mut ParseCache<'a>,
            ) -> ParseResult<'a, Parsed> {
                let mut iterations: usize = 0;
                let mut state = state;
                let mut part: Vec<PartNode> = Vec::new();
                loop {
                    match ChoiceHelper::new(state.clone())
                        .choice(|state| {
                            parse_Whitespace(state, tracer, cache)
                                .and_then(|ParseOk { state, .. }| parse_PartNode(state, tracer, cache))
                                .map_inner(|result| vec![result])
                        })
                        .choice(|state| {
                            parse_Whitespace(state, tracer, cache)
                                .and_then(|ParseOk { state, .. }| parse_Split(state, tracer, cache))
                                .discard_result()
                                .map_inner(|_| Vec::new())
                        })
                        .end()
                    {
                        Ok(ParseOk { result: __result, state: new_state, .. }) => {
                            part.extend(__result);
                            state = new_state;
                        }
                        Err(err) => {
                            state = state.record_error(err);
                            break;
                        }
                    }
                    iterations += 1;
                }
                Ok(ParseOk { result: part, state })
            }
            pub type Parsed = Vec<PartNode>;
        }
        #[inline(always)]
        pub fn parse<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, Parsed> {
            let ParseOk { result: mut part, state } = part_0::parse(state, tracer, cache)?;
            let ParseOk { state, .. } =
                parse_Whitespace(state, tracer, cache).and_then(|ParseOk { state, .. }| parse_end_of_input(state))?;
            Ok(ParseOk { result: part, state })
        }
        pub type Parsed = Vec<PartNode>;
        #[inline(always)]
        pub fn rule_parser<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, super::PromptNode> {
            let result = parse(state, tracer, cache)?.map(|r| super::PromptNode { part: r });
            Ok(result)
        }
    }
    #[inline]
    pub(super) fn parse_PromptNode<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, PromptNode> {
        tracer.run_traced("PromptNode", state, |state, tracer| PromptNode_impl::rule_parser(state, tracer, cache))
    }
    mod PartNode_impl {
        use super::*;
        #[inline(always)]
        pub fn parse<'a>(
            mut state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, Parsed> {
            ChoiceHelper::new(state)
                .choice(|state| {
                    parse_Whitespace(state, tracer, cache)
                        .and_then(|ParseOk { state, .. }| parse_StrongNode(state, tracer, cache))
                        .map_inner(Parsed__override::StrongNode)
                })
                .choice(|state| {
                    parse_Whitespace(state, tracer, cache)
                        .and_then(|ParseOk { state, .. }| parse_WeakNode(state, tracer, cache))
                        .map_inner(Parsed__override::WeakNode)
                })
                .choice(|state| {
                    parse_Whitespace(state, tracer, cache)
                        .and_then(|ParseOk { state, .. }| parse_TotalNode(state, tracer, cache))
                        .map_inner(Parsed__override::TotalNode)
                })
                .choice(|state| {
                    parse_Whitespace(state, tracer, cache)
                        .and_then(|ParseOk { state, .. }| parse_NumNode(state, tracer, cache))
                        .map_inner(Parsed__override::NumNode)
                })
                .choice(|state| {
                    parse_Whitespace(state, tracer, cache)
                        .and_then(|ParseOk { state, .. }| parse_WordNode(state, tracer, cache))
                        .map_inner(Parsed__override::WordNode)
                })
                .end()
        }
        pub type Parsed = Parsed__override;
        use super::PartNode as Parsed__override;
        #[inline(always)]
        pub fn rule_parser<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, super::PartNode> {
            let result = parse(state, tracer, cache)?;
            Ok(result)
        }
    }
    #[inline]
    pub(super) fn parse_PartNode<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, PartNode> {
        tracer.run_traced("PartNode", state, |state, tracer| PartNode_impl::rule_parser(state, tracer, cache))
    }
    impl PegPosition for PartNode {
        fn position(&self) -> &std::ops::Range<usize> {
            match self {
                Self::NumNode(x) => x.position(),
                Self::StrongNode(x) => x.position(),
                Self::TotalNode(x) => x.position(),
                Self::WeakNode(x) => x.position(),
                Self::WordNode(x) => x.position(),
            }
        }
    }
    mod WordNode_impl {
        use super::*;
        mod closure {
            use super::*;
        }
        #[inline(always)]
        pub fn parse<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, Parsed> {
            let mut iterations: usize = 0;
            let mut state = state;
            let mut id: Vec<IdentNode> = Vec::new();
            loop {
                match parse_Whitespace(state.clone(), tracer, cache)
                    .and_then(|ParseOk { state, .. }| parse_IdentNode(state, tracer, cache))
                    .map_inner(|result| vec![result])
                {
                    Ok(ParseOk { result: __result, state: new_state, .. }) => {
                        id.extend(__result);
                        state = new_state;
                    }
                    Err(err) => {
                        state = state.record_error(err);
                        break;
                    }
                }
                iterations += 1;
            }
            if iterations == 0 {
                return Err(state.report_farthest_error());
            }
            Ok(ParseOk { result: id, state })
        }
        pub type Parsed = Vec<IdentNode>;
        #[inline(always)]
        pub fn rule_parser<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, super::WordNode> {
            let result = parse(state.clone(), tracer, cache)?
                .map_with_state(|r, new_state| super::WordNode { id: r, position: state.range_until(new_state) });
            Ok(result)
        }
    }
    #[inline]
    pub(super) fn parse_WordNode<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, WordNode> {
        tracer.run_traced("WordNode", state, |state, tracer| WordNode_impl::rule_parser(state, tracer, cache))
    }
    impl PegPosition for WordNode {
        fn position(&self) -> &std::ops::Range<usize> {
            &self.position
        }
    }
    mod StrongNode_impl {
        use super::*;
        mod part_1 {
            use super::*;
            mod closure {
                use super::*;
            }
            #[inline(always)]
            pub fn parse<'a>(
                state: ParseState<'a>,
                tracer: impl ParseTracer,
                cache: &mut ParseCache<'a>,
            ) -> ParseResult<'a, Parsed> {
                let mut iterations: usize = 0;
                let mut state = state;
                let mut parts: Vec<PartNode> = Vec::new();
                loop {
                    match ChoiceHelper::new(state.clone())
                        .choice(|state| {
                            parse_Whitespace(state, tracer, cache)
                                .and_then(|ParseOk { state, .. }| parse_PartNode(state, tracer, cache))
                                .map_inner(|result| vec![result])
                        })
                        .choice(|state| {
                            parse_Whitespace(state, tracer, cache)
                                .and_then(|ParseOk { state, .. }| parse_Split(state, tracer, cache))
                                .discard_result()
                                .map_inner(|_| Vec::new())
                        })
                        .end()
                    {
                        Ok(ParseOk { result: __result, state: new_state, .. }) => {
                            parts.extend(__result);
                            state = new_state;
                        }
                        Err(err) => {
                            state = state.record_error(err);
                            break;
                        }
                    }
                    iterations += 1;
                }
                Ok(ParseOk { result: parts, state })
            }
            pub type Parsed = Vec<PartNode>;
        }
        mod part_3 {
            use super::*;
            mod optional {
                use super::*;
                #[inline(always)]
                pub fn parse<'a>(
                    state: ParseState<'a>,
                    tracer: impl ParseTracer,
                    cache: &mut ParseCache<'a>,
                ) -> ParseResult<'a, Parsed> {
                    let ParseOk { state, .. } = parse_Whitespace(state, tracer, cache)
                        .and_then(|ParseOk { state, .. }| parse_Times(state, tracer, cache))
                        .discard_result()?;
                    let ParseOk { result: num, state } = parse_Whitespace(state, tracer, cache)
                        .and_then(|ParseOk { state, .. }| parse_NumNode(state, tracer, cache))
                        .map_inner(Some)?;
                    Ok(ParseOk { result: num, state })
                }
                pub type Parsed = Option<NumNode>;
            }
            #[inline(always)]
            pub fn parse<'a>(
                state: ParseState<'a>,
                tracer: impl ParseTracer,
                cache: &mut ParseCache<'a>,
            ) -> ParseResult<'a, Parsed> {
                optional::parse(state.clone(), tracer, cache)
                    .or_else(|err| Ok(ParseOk { result: Default::default(), state: state.record_error(err) }))
            }
            pub type Parsed = Option<NumNode>;
        }
        #[inline(always)]
        pub fn parse<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, Parsed> {
            let ParseOk { state, .. } = parse_Whitespace(state, tracer, cache)
                .and_then(|ParseOk { state, .. }| parse_character_literal(state, '{'))
                .discard_result()?;
            let ParseOk { result: mut parts, state } = part_1::parse(state, tracer, cache)?;
            let ParseOk { state, .. } = parse_Whitespace(state, tracer, cache)
                .and_then(|ParseOk { state, .. }| parse_character_literal(state, '}'))
                .discard_result()?;
            let ParseOk { result: num, state } = part_3::parse(state, tracer, cache)?;
            Ok(ParseOk { result: Parsed { parts, num }, state })
        }
        pub struct Parsed {
            pub parts: Vec<PartNode>,
            pub num: Option<NumNode>,
        }
        #[inline(always)]
        pub fn rule_parser<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, super::StrongNode> {
            let result = parse(state.clone(), tracer, cache)?.map_with_state(|r, new_state| super::StrongNode {
                parts: r.parts,
                num: r.num,
                position: state.range_until(new_state),
            });
            Ok(result)
        }
    }
    #[inline]
    pub(super) fn parse_StrongNode<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, StrongNode> {
        tracer.run_traced("StrongNode", state, |state, tracer| StrongNode_impl::rule_parser(state, tracer, cache))
    }
    impl PegPosition for StrongNode {
        fn position(&self) -> &std::ops::Range<usize> {
            &self.position
        }
    }
    mod WeakNode_impl {
        use super::*;
        mod part_1 {
            use super::*;
            mod closure {
                use super::*;
            }
            #[inline(always)]
            pub fn parse<'a>(
                state: ParseState<'a>,
                tracer: impl ParseTracer,
                cache: &mut ParseCache<'a>,
            ) -> ParseResult<'a, Parsed> {
                let mut iterations: usize = 0;
                let mut state = state;
                let mut parts: Vec<PartNode> = Vec::new();
                loop {
                    match ChoiceHelper::new(state.clone())
                        .choice(|state| {
                            parse_Whitespace(state, tracer, cache)
                                .and_then(|ParseOk { state, .. }| parse_PartNode(state, tracer, cache))
                                .map_inner(|result| vec![result])
                        })
                        .choice(|state| {
                            parse_Whitespace(state, tracer, cache)
                                .and_then(|ParseOk { state, .. }| parse_Split(state, tracer, cache))
                                .discard_result()
                                .map_inner(|_| Vec::new())
                        })
                        .end()
                    {
                        Ok(ParseOk { result: __result, state: new_state, .. }) => {
                            parts.extend(__result);
                            state = new_state;
                        }
                        Err(err) => {
                            state = state.record_error(err);
                            break;
                        }
                    }
                    iterations += 1;
                }
                Ok(ParseOk { result: parts, state })
            }
            pub type Parsed = Vec<PartNode>;
        }
        mod part_3 {
            use super::*;
            mod optional {
                use super::*;
                #[inline(always)]
                pub fn parse<'a>(
                    state: ParseState<'a>,
                    tracer: impl ParseTracer,
                    cache: &mut ParseCache<'a>,
                ) -> ParseResult<'a, Parsed> {
                    let ParseOk { state, .. } = parse_Whitespace(state, tracer, cache)
                        .and_then(|ParseOk { state, .. }| parse_Times(state, tracer, cache))
                        .discard_result()?;
                    let ParseOk { result: num, state } = parse_Whitespace(state, tracer, cache)
                        .and_then(|ParseOk { state, .. }| parse_NumNode(state, tracer, cache))
                        .map_inner(Some)?;
                    Ok(ParseOk { result: num, state })
                }
                pub type Parsed = Option<NumNode>;
            }
            #[inline(always)]
            pub fn parse<'a>(
                state: ParseState<'a>,
                tracer: impl ParseTracer,
                cache: &mut ParseCache<'a>,
            ) -> ParseResult<'a, Parsed> {
                optional::parse(state.clone(), tracer, cache)
                    .or_else(|err| Ok(ParseOk { result: Default::default(), state: state.record_error(err) }))
            }
            pub type Parsed = Option<NumNode>;
        }
        #[inline(always)]
        pub fn parse<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, Parsed> {
            let ParseOk { state, .. } = parse_Whitespace(state, tracer, cache)
                .and_then(|ParseOk { state, .. }| parse_character_literal(state, '['))
                .discard_result()?;
            let ParseOk { result: mut parts, state } = part_1::parse(state, tracer, cache)?;
            let ParseOk { state, .. } = parse_Whitespace(state, tracer, cache)
                .and_then(|ParseOk { state, .. }| parse_character_literal(state, ']'))
                .discard_result()?;
            let ParseOk { result: num, state } = part_3::parse(state, tracer, cache)?;
            Ok(ParseOk { result: Parsed { parts, num }, state })
        }
        pub struct Parsed {
            pub parts: Vec<PartNode>,
            pub num: Option<NumNode>,
        }
        #[inline(always)]
        pub fn rule_parser<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, super::WeakNode> {
            let result = parse(state.clone(), tracer, cache)?.map_with_state(|r, new_state| super::WeakNode {
                parts: r.parts,
                num: r.num,
                position: state.range_until(new_state),
            });
            Ok(result)
        }
    }
    #[inline]
    pub(super) fn parse_WeakNode<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, WeakNode> {
        tracer.run_traced("WeakNode", state, |state, tracer| WeakNode_impl::rule_parser(state, tracer, cache))
    }
    impl PegPosition for WeakNode {
        fn position(&self) -> &std::ops::Range<usize> {
            &self.position
        }
    }
    mod TotalNode_impl {
        use super::*;
        mod part_1 {
            use super::*;
            mod closure {
                use super::*;
            }
            #[inline(always)]
            pub fn parse<'a>(
                state: ParseState<'a>,
                tracer: impl ParseTracer,
                cache: &mut ParseCache<'a>,
            ) -> ParseResult<'a, Parsed> {
                let mut iterations: usize = 0;
                let mut state = state;
                let mut parts: Vec<PartNode> = Vec::new();
                loop {
                    match ChoiceHelper::new(state.clone())
                        .choice(|state| {
                            parse_Whitespace(state, tracer, cache)
                                .and_then(|ParseOk { state, .. }| parse_PartNode(state, tracer, cache))
                                .map_inner(|result| vec![result])
                        })
                        .choice(|state| {
                            parse_Whitespace(state, tracer, cache)
                                .and_then(|ParseOk { state, .. }| parse_Split(state, tracer, cache))
                                .discard_result()
                                .map_inner(|_| Vec::new())
                        })
                        .end()
                    {
                        Ok(ParseOk { result: __result, state: new_state, .. }) => {
                            parts.extend(__result);
                            state = new_state;
                        }
                        Err(err) => {
                            state = state.record_error(err);
                            break;
                        }
                    }
                    iterations += 1;
                }
                Ok(ParseOk { result: parts, state })
            }
            pub type Parsed = Vec<PartNode>;
        }
        #[inline(always)]
        pub fn parse<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, Parsed> {
            let ParseOk { state, .. } = parse_Whitespace(state, tracer, cache)
                .and_then(|ParseOk { state, .. }| parse_character_literal(state, '('))
                .discard_result()?;
            let ParseOk { result: mut parts, state } = part_1::parse(state, tracer, cache)?;
            let ParseOk { state, .. } = parse_Whitespace(state, tracer, cache)
                .and_then(|ParseOk { state, .. }| parse_character_literal(state, ')'))
                .discard_result()?;
            Ok(ParseOk { result: parts, state })
        }
        pub type Parsed = Vec<PartNode>;
        #[inline(always)]
        pub fn rule_parser<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, super::TotalNode> {
            let result = parse(state.clone(), tracer, cache)?
                .map_with_state(|r, new_state| super::TotalNode { parts: r, position: state.range_until(new_state) });
            Ok(result)
        }
    }
    #[inline]
    pub(super) fn parse_TotalNode<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, TotalNode> {
        tracer.run_traced("TotalNode", state, |state, tracer| TotalNode_impl::rule_parser(state, tracer, cache))
    }
    impl PegPosition for TotalNode {
        fn position(&self) -> &std::ops::Range<usize> {
            &self.position
        }
    }
    #[inline]
    pub(super) fn parse_Split<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, Split> {
        if let Ok(result) = parse_character_literal(state.clone(), ',') {
            return Ok(result);
        }
        if let Ok(result) = parse_character_literal(state.clone(), '，') {
            return Ok(result);
        }
        Err(state.report_error(ParseErrorSpecifics::ExpectedCharacterClass { name: "Split" }))
    }
    #[inline]
    pub(super) fn parse_Times<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, Times> {
        if let Ok(result) = parse_character_literal(state.clone(), '*') {
            return Ok(result);
        }
        if let Ok(result) = parse_character_literal(state.clone(), '×') {
            return Ok(result);
        }
        Err(state.report_error(ParseErrorSpecifics::ExpectedCharacterClass { name: "Times" }))
    }
    mod NumNode_impl {
        use super::*;
        mod closure {
            use super::*;
        }
        #[inline(always)]
        pub fn parse<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, Parsed> {
            let mut iterations: usize = 0;
            let mut state = state;
            loop {
                match parse_character_range(state.clone(), '0', '9').discard_result() {
                    Ok(ParseOk { result: __result, state: new_state, .. }) => {
                        state = new_state;
                    }
                    Err(err) => {
                        state = state.record_error(err);
                        break;
                    }
                }
                iterations += 1;
            }
            if iterations == 0 {
                return Err(state.report_farthest_error());
            }
            Ok(ParseOk { result: (), state })
        }
        pub type Parsed = ();
        #[inline(always)]
        pub fn rule_parser<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, NumNode> {
            let result = parse(state.clone(), tracer, cache)?.map_with_state(|_, new_state| {
                let string = state.slice_until(new_state).to_string();
                NumNode { string, position: state.range_until(new_state) }
            });
            Ok(result)
        }
    }
    #[inline]
    pub(super) fn parse_NumNode<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, NumNode> {
        tracer.run_traced("NumNode", state, |state, tracer| NumNode_impl::rule_parser(state, tracer, cache))
    }
    impl PegPosition for NumNode {
        fn position(&self) -> &std::ops::Range<usize> {
            &self.position
        }
    }
    mod IdentNode_impl {
        use super::*;
        mod closure {
            use super::*;
        }
        #[inline(always)]
        pub fn parse<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, Parsed> {
            let mut iterations: usize = 0;
            let mut state = state;
            loop {
                match ChoiceHelper::new(state.clone())
                    .choice(|state| parse_XID_CONTINUE(state, tracer, cache).discard_result())
                    .choice(|state| parse_character_literal(state, '-').discard_result())
                    .end()
                {
                    Ok(ParseOk { result: __result, state: new_state, .. }) => {
                        state = new_state;
                    }
                    Err(err) => {
                        state = state.record_error(err);
                        break;
                    }
                }
                iterations += 1;
            }
            if iterations == 0 {
                return Err(state.report_farthest_error());
            }
            Ok(ParseOk { result: (), state })
        }
        pub type Parsed = ();
        #[inline(always)]
        pub fn rule_parser<'a>(
            state: ParseState<'a>,
            tracer: impl ParseTracer,
            cache: &mut ParseCache<'a>,
        ) -> ParseResult<'a, IdentNode> {
            let result = parse(state.clone(), tracer, cache)?.map_with_state(|_, new_state| {
                let string = state.slice_until(new_state).to_string();
                IdentNode { string, position: state.range_until(new_state) }
            });
            Ok(result)
        }
    }
    #[inline]
    pub(super) fn parse_IdentNode<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, IdentNode> {
        tracer.run_traced("IdentNode", state, |state, tracer| IdentNode_impl::rule_parser(state, tracer, cache))
    }
    impl PegPosition for IdentNode {
        fn position(&self) -> &std::ops::Range<usize> {
            &self.position
        }
    }
    #[inline]
    pub(super) fn parse_XID_CONTINUE<'a>(
        state: ParseState<'a>,
        tracer: impl ParseTracer,
        cache: &mut ParseCache<'a>,
    ) -> ParseResult<'a, XID_CONTINUE> {
        if let Some(c) = state.s().chars().next() {
            if !unicode_ident::is_xid_continue(c) {
                return Err(state.report_error(ParseErrorSpecifics::ExpectedCharacterClass { name: "XID_CONTINUE" }));
            }
        }
        else {
            return Err(state.report_error(ParseErrorSpecifics::ExpectedCharacterClass { name: "XID_CONTINUE" }));
        }
        if let Ok(result) = parse_char(state.clone(), tracer, cache) {
            return Ok(result);
        }
        Err(state.report_error(ParseErrorSpecifics::ExpectedCharacterClass { name: "XID_CONTINUE" }))
    }
}
