@@ -139,34 +139,30 @@ const group = P.choice([
139139
140140// Need to backtrack on bounded quantifier because if the curly bracket is
141141// not terminated (e.g. "a{2,3") then all characters are interpreted literally.
142+ // The same if min value is missing but max value is given (e.g. "a{,3}").
143+ //
142144// FIXME: However, this breaks something else. E.g. "a*{3}" must still be rejected as
143145// invalid and not interpreted as "a*" and then literal charactesr "{3}".
144146const boundedQuantifier : P . Expr . UnaryOperator < AST . RegExpAST > = P . tryElseBacktrack (
145147 P . between (
146148 P . string ( '{' ) ,
147149 P . string ( '}' ) ,
148- P . optional ( P . decimal ) . andThen ( min => {
149- if ( min === undefined )
150- // e.g. a{,5}
151- return P . string ( ',' )
152- . andThen ( _ => P . decimal )
153- . map ( max => inner => AST . repeat ( inner , { max } ) )
154- else
155- return P . optional ( P . string ( ',' ) ) . andThen ( comma => {
156- if ( comma === undefined )
157- // e.g. a{3}
158- return P . pure ( inner => AST . repeat ( inner , min ) )
159- else
160- return P . optional ( P . decimal ) . map ( max => inner => {
161- if ( max === undefined )
162- // e.g. a{3,}
163- return AST . repeat ( inner , { min } )
164- else
165- // e.g. a{3,5}
166- return AST . repeat ( inner , { min, max } )
167- } )
168- } )
169- } )
150+ P . decimal . andThen ( min =>
151+ P . optional ( P . string ( ',' ) ) . andThen ( comma => {
152+ if ( comma === undefined )
153+ // e.g. a{3}
154+ return P . pure ( inner => AST . repeat ( inner , min ) )
155+ else
156+ return P . optional ( P . decimal ) . map ( max => inner => {
157+ if ( max === undefined )
158+ // e.g. a{3,}
159+ return AST . repeat ( inner , { min } )
160+ else
161+ // e.g. a{3,5}
162+ return AST . repeat ( inner , { min, max } )
163+ } )
164+ } )
165+ )
170166 )
171167)
172168
0 commit comments