@@ -35,9 +35,9 @@ use super::{Input, Token};
3535
3636pub ( super ) type PResult < ' i , ' b , T > = IResult < Input < ' i , ' b > , T , ParseError > ;
3737
38- pub ( crate ) fn parse ( source : & str ) -> Result < Rule < ' _ > , ParseError > {
38+ pub ( crate ) fn parse ( source : & str , recursion : u16 ) -> Result < Rule < ' _ > , ParseError > {
3939 let tokens = super :: tokenize:: tokenize ( source) ;
40- let input = Input :: from ( source, & tokens) ?;
40+ let input = Input :: from ( source, & tokens, recursion ) ?;
4141
4242 let ( rest, rules) = parse_modified ( input) ?;
4343 if rest. is_empty ( ) {
@@ -47,6 +47,22 @@ pub(crate) fn parse(source: &str) -> Result<Rule<'_>, ParseError> {
4747 }
4848}
4949
50+ fn recurse < ' i , ' b , O > (
51+ mut parser : impl Parser < Input < ' i , ' b > , O , ParseError > ,
52+ ) -> impl FnMut ( Input < ' i , ' b > ) -> PResult < ' i , ' b , O > {
53+ move |mut input| {
54+ input. recursion_start ( ) . map_err ( nom:: Err :: Failure ) ?;
55+
56+ match parser. parse ( input) {
57+ Ok ( ( mut input, output) ) => {
58+ input. recursion_end ( ) ;
59+ Ok ( ( input, output) )
60+ }
61+ Err ( e) => Err ( e) ,
62+ }
63+ }
64+ }
65+
5066pub ( super ) fn parse_modified < ' i , ' b > ( input : Input < ' i , ' b > ) -> PResult < ' i , ' b , Rule < ' i > > {
5167 enum ModifierKind {
5268 Enable ,
@@ -78,15 +94,15 @@ pub(super) fn parse_modified<'i, 'b>(input: Input<'i, 'b>) -> PResult<'i, 'b, Ru
7894 "let" ,
7995 cut ( Token :: Identifier ) ,
8096 cut ( Token :: Equals ) ,
81- cut ( parse_or) ,
97+ cut ( recurse ( parse_or) ) ,
8298 cut ( Token :: Semicolon ) ,
8399 ) ) ,
84100 |( ( _, span_start) , ( name, name_span) , _, rule, ( _, span_end) ) | {
85101 ( Stmt :: Let ( Let :: new ( name, rule, name_span) ) , span_start. join ( span_end) )
86102 } ,
87103 ) ,
88104 ) ) ) ,
89- parse_or,
105+ recurse ( parse_or) ,
90106 ) ,
91107 |( stmts, mut rule) : ( Vec < ( Stmt , Span ) > , _ ) | {
92108 if stmts. len ( ) > 1 {
@@ -137,7 +153,7 @@ pub(super) fn parse_sequence<'i, 'b>(input: Input<'i, 'b>) -> PResult<'i, 'b, Ru
137153pub ( super ) fn parse_fixes < ' i , ' b > ( input : Input < ' i , ' b > ) -> PResult < ' i , ' b , Rule < ' i > > {
138154 alt ( (
139155 try_map (
140- pair ( Token :: Not , opt ( parse_fixes) ) ,
156+ pair ( Token :: Not , opt ( recurse ( parse_fixes) ) ) ,
141157 |( _, rule) | {
142158 if let Some ( mut rule) = rule {
143159 rule. negate ( ) ?;
@@ -148,7 +164,7 @@ pub(super) fn parse_fixes<'i, 'b>(input: Input<'i, 'b>) -> PResult<'i, 'b, Rule<
148164 } ,
149165 nom:: Err :: Failure ,
150166 ) ,
151- map ( pair ( parse_lookaround, parse_modified) , |( ( kind, span) , rule) | {
167+ map ( pair ( parse_lookaround, recurse ( parse_modified) ) , |( ( kind, span) , rule) | {
152168 let span = span. join ( rule. span ( ) ) ;
153169 Rule :: Lookaround ( Box :: new ( Lookaround :: new ( rule, kind, span) ) )
154170 } ) ,
@@ -282,7 +298,10 @@ pub(super) fn parse_group<'i, 'b>(input: Input<'i, 'b>) -> PResult<'i, 'b, Rule<
282298 }
283299
284300 map (
285- pair ( opt ( parse_capture) , tuple ( ( Token :: OpenParen , parse_modified, cut ( Token :: CloseParen ) ) ) ) ,
301+ pair (
302+ opt ( parse_capture) ,
303+ tuple ( ( Token :: OpenParen , recurse ( parse_modified) , cut ( Token :: CloseParen ) ) ) ,
304+ ) ,
286305 |( capture, ( _, rule, ( _, close_paren) ) ) | match ( capture, rule) {
287306 ( None , rule) => rule,
288307 ( Some ( ( capture, c_span) ) , Rule :: Group ( mut g) ) if !g. is_capturing ( ) => {
0 commit comments