Parse a group (which contains a sub-expression) or a set of flags. If a group was found, then it is returned with an empty AST. If a set of flags is found, then that set is returned. The parser should be positioned at the opening parenthesis. This advances the parser to the character before the start of the sub-expression (in the case of a group) or to the closing parenthesis immediately follow
(&self)
| 1186 | /// If a capture name is given and it is incorrectly specified, then a |
| 1187 | /// corresponding error is returned. |
| 1188 | fn parse_group(&self) -> Result<Either<ast::SetFlags, ast::Group>> { |
| 1189 | assert_eq!(self.char(), '('); |
| 1190 | let open_span = self.span_char(); |
| 1191 | self.bump(); |
| 1192 | self.bump_space(); |
| 1193 | if self.is_lookaround_prefix() { |
| 1194 | return Err(self.error( |
| 1195 | Span::new(open_span.start, self.span().end), |
| 1196 | ast::ErrorKind::UnsupportedLookAround, |
| 1197 | )); |
| 1198 | } |
| 1199 | let inner_span = self.span(); |
| 1200 | if self.bump_if("?P<") { |
| 1201 | let capture_index = self.next_capture_index(open_span)?; |
| 1202 | let cap = self.parse_capture_name(capture_index)?; |
| 1203 | Ok(Either::Right(ast::Group { |
| 1204 | span: open_span, |
| 1205 | kind: ast::GroupKind::CaptureName(cap), |
| 1206 | ast: Box::new(Ast::Empty(self.span())), |
| 1207 | })) |
| 1208 | } else if self.bump_if("?") { |
| 1209 | if self.is_eof() { |
| 1210 | return Err(self.error( |
| 1211 | open_span, |
| 1212 | ast::ErrorKind::GroupUnclosed, |
| 1213 | )); |
| 1214 | } |
| 1215 | let flags = self.parse_flags()?; |
| 1216 | let char_end = self.char(); |
| 1217 | self.bump(); |
| 1218 | if char_end == ')' { |
| 1219 | // We don't allow empty flags, e.g., `(?)`. We instead |
| 1220 | // interpret it as a repetition operator missing its argument. |
| 1221 | if flags.items.is_empty() { |
| 1222 | return Err(self.error( |
| 1223 | inner_span, |
| 1224 | ast::ErrorKind::RepetitionMissing, |
| 1225 | )); |
| 1226 | } |
| 1227 | Ok(Either::Left(ast::SetFlags { |
| 1228 | span: Span { end: self.pos(), ..open_span }, |
| 1229 | flags: flags, |
| 1230 | })) |
| 1231 | } else { |
| 1232 | assert_eq!(char_end, ':'); |
| 1233 | Ok(Either::Right(ast::Group { |
| 1234 | span: open_span, |
| 1235 | kind: ast::GroupKind::NonCapturing(flags), |
| 1236 | ast: Box::new(Ast::Empty(self.span())), |
| 1237 | })) |
| 1238 | } |
| 1239 | } else { |
| 1240 | let capture_index = self.next_capture_index(open_span)?; |
| 1241 | Ok(Either::Right(ast::Group { |
| 1242 | span: open_span, |
| 1243 | kind: ast::GroupKind::CaptureIndex(capture_index), |
| 1244 | ast: Box::new(Ast::Empty(self.span())), |
| 1245 | })) |
no test coverage detected