/// they should impose a limit on the length, in bytes, of the concrete
/// pattern string. In particular, this is viable since this parser
/// implementation will limit itself to heap space proportional to the
- /// lenth of the pattern string.
+ /// length of the pattern string.
///
/// Note that a nest limit of `0` will return a nest limit error for most
/// patterns but not all. For example, a nest limit of `0` permits `a` but
/// Enable verbose mode in the regular expression.
///
- /// When enabled, verbose mode permits insigificant whitespace in many
+ /// When enabled, verbose mode permits insignificant whitespace in many
/// places in the regular expression, as well as comments. Comments are
/// started using `#` and continue until the end of the line.
///
/// supported.
octal: bool,
/// The initial setting for `ignore_whitespace` as provided by
- /// Th`ParserBuilder`. is is used when reseting the parser's state.
+ /// `ParserBuilder`. It is used when resetting the parser's state.
initial_ignore_whitespace: bool,
/// Whether whitespace should be ignored. When enabled, comments are
/// also permitted.
impl<'s, P: Borrow<Parser>> ParserI<'s, P> {
/// Build an internal parser from a parser configuration and a pattern.
fn new(parser: P, pattern: &'s str) -> ParserI<'s, P> {
- ParserI { parser: parser, pattern: pattern }
+ ParserI { parser, pattern }
}
/// Return a reference to the parser state.
/// Create a new error with the given span and error type.
fn error(&self, span: Span, kind: ast::ErrorKind) -> ast::Error {
- ast::Error {
- kind: kind,
- pattern: self.pattern().to_string(),
- span: span,
- }
+ ast::Error { kind, pattern: self.pattern().to_string(), span }
}
/// Return the current offset of the parser.
column = column.checked_add(1).unwrap();
}
offset += self.char().len_utf8();
- self.parser().pos.set(Position {
- offset: offset,
- line: line,
- column: column,
- });
+ self.parser().pos.set(Position { offset, line, column });
self.pattern()[self.offset()..].chars().next().is_some()
}
.unwrap_or(old_ignore_whitespace);
self.parser().stack_group.borrow_mut().push(
GroupState::Group {
- concat: concat,
- group: group,
+ concat,
+ group,
ignore_whitespace: old_ignore_whitespace,
},
);
#[inline(never)]
fn unclosed_class_error(&self) -> ast::Error {
for state in self.parser().stack_class.borrow().iter().rev() {
- match *state {
- ClassState::Open { ref set, .. } => {
- return self
- .error(set.span, ast::ErrorKind::ClassUnclosed);
- }
- _ => {}
+ if let ClassState::Open { ref set, .. } = *state {
+ return self.error(set.span, ast::ErrorKind::ClassUnclosed);
}
}
// We are guaranteed to have a non-empty stack with at least
};
let span = Span::new(lhs.span().start, rhs.span().end);
ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
- span: span,
- kind: kind,
+ span,
+ kind,
lhs: Box::new(lhs),
rhs: Box::new(rhs),
})
let ast = self.pop_group_end(concat)?;
NestLimiter::new(self).check(&ast)?;
Ok(ast::WithComments {
- ast: ast,
+ ast,
comments: mem::replace(
&mut *self.parser().comments.borrow_mut(),
vec![],
/// The given `kind` should correspond to the operator observed by the
/// caller.
///
- /// This assumes that the paser is currently positioned at the repetition
+ /// This assumes that the parser is currently positioned at the repetition
/// operator and advances the parser to the first character after the
/// operator. (Note that the operator may include a single additional `?`,
/// which makes the operator ungreedy.)
span: ast.span().with_end(self.pos()),
op: ast::RepetitionOp {
span: Span::new(op_start, self.pos()),
- kind: kind,
+ kind,
},
- greedy: greedy,
+ greedy,
ast: Box::new(ast),
}));
Ok(concat)
/// corresponds to the {m,n} syntax, and does not include the ?, * or +
/// operators.
///
- /// This assumes that the paser is currently positioned at the opening `{`
+ /// This assumes that the parser is currently positioned at the opening `{`
/// and advances the parser to the first character after the operator.
/// (Note that the operator may include a single additional `?`, which
/// makes the operator ungreedy.)
span: op_span,
kind: ast::RepetitionKind::Range(range),
},
- greedy: greedy,
+ greedy,
ast: Box::new(ast),
}));
Ok(concat)
}
Ok(Either::Left(ast::SetFlags {
span: Span { end: self.pos(), ..open_span },
- flags: flags,
+ flags,
}))
} else {
assert_eq!(char_end, ':');
let ast = Primitive::Literal(ast::Literal {
span: self.span_char(),
kind: ast::LiteralKind::Verbatim,
- c: c,
+ c,
});
self.bump();
Ok(ast)
let span = Span::new(start, self.pos());
if is_meta_character(c) {
return Ok(Primitive::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Punctuation,
- c: c,
+ c,
}));
}
let special = |kind, c| {
Ok(Primitive::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Special(kind),
- c: c,
+ c,
}))
};
match c {
special(ast::SpecialLiteralKind::Space, ' ')
}
'A' => Ok(Primitive::Assertion(ast::Assertion {
- span: span,
+ span,
kind: ast::AssertionKind::StartText,
})),
'z' => Ok(Primitive::Assertion(ast::Assertion {
- span: span,
+ span,
kind: ast::AssertionKind::EndText,
})),
'b' => Ok(Primitive::Assertion(ast::Assertion {
- span: span,
+ span,
kind: ast::AssertionKind::WordBoundary,
})),
'B' => Ok(Primitive::Assertion(ast::Assertion {
- span: span,
+ span,
kind: ast::AssertionKind::NotWordBoundary,
})),
_ => Err(self.error(span, ast::ErrorKind::EscapeUnrecognized)),
ast::Literal {
span: Span::new(start, end),
kind: ast::LiteralKind::Octal,
- c: c,
+ c,
}
}
Some(c) => Ok(ast::Literal {
span: Span::new(start, end),
kind: ast::LiteralKind::HexFixed(kind),
- c: c,
+ c,
}),
}
}
Some(c) => Ok(ast::Literal {
span: Span::new(start, self.pos()),
kind: ast::LiteralKind::HexBrace(kind),
- c: c,
+ c,
}),
}
}
}));
if !self.bump_and_bump_space() {
return Err(self.error(
- Span::new(start, self.pos()),
+ Span::new(start, start),
ast::ErrorKind::ClassUnclosed,
));
}
}
let set = ast::ClassBracketed {
span: Span::new(start, self.pos()),
- negated: negated,
+ negated,
kind: ast::ClassSet::union(ast::ClassSetUnion {
span: Span::new(union.span.start, union.span.start),
items: vec![],
};
Some(ast::ClassAscii {
span: Span::new(start, self.pos()),
- kind: kind,
- negated: negated,
+ kind,
+ negated,
})
}
};
Ok(ast::ClassUnicode {
span: Span::new(start, self.pos()),
- negated: negated,
- kind: kind,
+ negated,
+ kind,
})
}
'W' => (true, ast::ClassPerlKind::Word),
c => panic!("expected valid Perl class but got '{}'", c),
};
- ast::ClassPerl { span: span, kind: kind, negated: negated }
+ ast::ClassPerl { span, kind, negated }
}
}
impl<'p, 's, P: Borrow<Parser>> NestLimiter<'p, 's, P> {
fn new(p: &'p ParserI<'s, P>) -> NestLimiter<'p, 's, P> {
- NestLimiter { p: p, depth: 0 }
+ NestLimiter { p, depth: 0 }
}
#[inline(never)]
/// Create a punctuation literal starting at the given position.
fn punct_lit(c: char, span: Span) -> Ast {
Ast::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Punctuation,
- c: c,
+ c,
})
}
/// Create a verbatim literal with the given span.
fn lit_with(c: char, span: Span) -> Ast {
Ast::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Verbatim,
- c: c,
+ c,
})
}
/// Create a concatenation with the given span.
fn concat_with(span: Span, asts: Vec<Ast>) -> Ast {
- Ast::Concat(ast::Concat { span: span, asts: asts })
+ Ast::Concat(ast::Concat { span, asts })
}
/// Create an alternation with the given span.
fn alt(range: Range<usize>, asts: Vec<Ast>) -> Ast {
- Ast::Alternation(ast::Alternation { span: span(range), asts: asts })
+ Ast::Alternation(ast::Alternation { span: span(range), asts })
}
/// Create a capturing group with the given span.
span: span_range(pat, range.clone()),
flags: ast::Flags {
span: span_range(pat, (range.start + 2)..(range.end - 1)),
- items: items,
+ items,
},
})
}
Ok(Primitive::Literal(ast::Literal {
span: span(0..2),
kind: ast::LiteralKind::Special(kind.clone()),
- c: c,
+ c,
}))
);
}
kind: ast::LiteralKind::HexFixed(
ast::HexLiteralKind::UnicodeShort
),
- c: c,
+ c,
}))
);
}
kind: ast::LiteralKind::HexFixed(
ast::HexLiteralKind::UnicodeLong
),
- c: c,
+ c,
}))
);
}
#[test]
fn parse_set_class() {
fn union(span: Span, items: Vec<ast::ClassSetItem>) -> ast::ClassSet {
- ast::ClassSet::union(ast::ClassSetUnion {
- span: span,
- items: items,
- })
+ ast::ClassSet::union(ast::ClassSetUnion { span, items })
}
fn intersection(
rhs: ast::ClassSet,
) -> ast::ClassSet {
ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
- span: span,
+ span,
kind: ast::ClassSetBinaryOpKind::Intersection,
lhs: Box::new(lhs),
rhs: Box::new(rhs),
rhs: ast::ClassSet,
) -> ast::ClassSet {
ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
- span: span,
+ span,
kind: ast::ClassSetBinaryOpKind::Difference,
lhs: Box::new(lhs),
rhs: Box::new(rhs),
rhs: ast::ClassSet,
) -> ast::ClassSet {
ast::ClassSet::BinaryOp(ast::ClassSetBinaryOp {
- span: span,
+ span,
kind: ast::ClassSetBinaryOpKind::SymmetricDifference,
lhs: Box::new(lhs),
rhs: Box::new(rhs),
fn lit(span: Span, c: char) -> ast::ClassSetItem {
ast::ClassSetItem::Literal(ast::Literal {
- span: span,
+ span,
kind: ast::LiteralKind::Verbatim,
- c: c,
+ c,
})
}
..span.end
};
ast::ClassSetItem::Range(ast::ClassSetRange {
- span: span,
+ span,
start: ast::Literal {
span: Span { end: pos1, ..span },
kind: ast::LiteralKind::Verbatim,
}
fn alnum(span: Span, negated: bool) -> ast::ClassAscii {
- ast::ClassAscii {
- span: span,
- kind: ast::ClassAsciiKind::Alnum,
- negated: negated,
- }
+ ast::ClassAscii { span, kind: ast::ClassAsciiKind::Alnum, negated }
}
fn lower(span: Span, negated: bool) -> ast::ClassAscii {
- ast::ClassAscii {
- span: span,
- kind: ast::ClassAsciiKind::Lower,
- negated: negated,
- }
+ ast::ClassAscii { span, kind: ast::ClassAsciiKind::Lower, negated }
}
assert_eq!(
assert_eq!(
parser("[-").parse_set_class_open().unwrap_err(),
TestError {
- span: span(0..2),
+ span: span(0..0),
kind: ast::ErrorKind::ClassUnclosed,
}
);
assert_eq!(
parser("[--").parse_set_class_open().unwrap_err(),
TestError {
- span: span(0..3),
+ span: span(0..0),
+ kind: ast::ErrorKind::ClassUnclosed,
+ }
+ );
+
+ // See: https://github.com/rust-lang/regex/issues/792
+ assert_eq!(
+ parser("(?x)[-#]").parse_with_comments().unwrap_err(),
+ TestError {
+ span: span(4..4),
kind: ast::ErrorKind::ClassUnclosed,
}
);