Refactor.

This commit is contained in:
Stephen Chung 2020-06-26 22:03:21 +08:00
parent 8c632ed928
commit 74c82bbd9c

View File

@ -434,15 +434,15 @@ impl From<Token> for String {
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default)]
pub struct TokenizeState { pub struct TokenizeState {
/// Maximum length of a string (0 = unlimited). /// Maximum length of a string (0 = unlimited).
max_string_size: usize, pub max_string_size: usize,
/// Can the next token be a unary operator? /// Can the next token be a unary operator?
can_be_unary: bool, pub non_unary: bool,
/// Is the tokenizer currently inside a block comment? /// Is the tokenizer currently inside a block comment?
comment_level: usize, pub comment_level: usize,
/// Return `None` at the end of the stream instead of `Some(Token::EOF)`? /// Return `None` at the end of the stream instead of `Some(Token::EOF)`?
end_with_none: bool, pub end_with_none: bool,
/// Include comments? /// Include comments?
include_comments: bool, pub include_comments: bool,
} }
/// Trait that encapsulates a peekable character input stream. /// Trait that encapsulates a peekable character input stream.
@ -620,7 +620,23 @@ fn scan_comment(
} }
/// Get the next token. /// Get the next token.
pub fn get_next_token( fn get_next_token(
stream: &mut impl InputStream,
state: &mut TokenizeState,
pos: &mut Position,
) -> Option<(Token, Position)> {
let result = get_next_token_inner(stream, state, pos);
// Save the last token's state
if let Some((token, _)) = &result {
state.non_unary = !token.is_next_unary();
}
result
}
/// Get the next token.
fn get_next_token_inner(
stream: &mut impl InputStream, stream: &mut impl InputStream,
state: &mut TokenizeState, state: &mut TokenizeState,
pos: &mut Position, pos: &mut Position,
@ -628,7 +644,7 @@ pub fn get_next_token(
// Still inside a comment? // Still inside a comment?
if state.comment_level > 0 { if state.comment_level > 0 {
let start_pos = *pos; let start_pos = *pos;
let mut comment = Default::default(); let mut comment = String::new();
scan_comment(stream, state, pos, &mut comment); scan_comment(stream, state, pos, &mut comment);
if state.include_comments { if state.include_comments {
@ -872,10 +888,10 @@ pub fn get_next_token(
eat_next(stream, pos); eat_next(stream, pos);
return Some((Token::PlusAssign, start_pos)); return Some((Token::PlusAssign, start_pos));
} }
('+', _) if state.can_be_unary => return Some((Token::UnaryPlus, start_pos)), ('+', _) if !state.non_unary => return Some((Token::UnaryPlus, start_pos)),
('+', _) => return Some((Token::Plus, start_pos)), ('+', _) => return Some((Token::Plus, start_pos)),
('-', '0'..='9') if state.can_be_unary => negated = true, ('-', '0'..='9') if !state.non_unary => negated = true,
('-', '0'..='9') => return Some((Token::Minus, start_pos)), ('-', '0'..='9') => return Some((Token::Minus, start_pos)),
('-', '=') => { ('-', '=') => {
eat_next(stream, pos); eat_next(stream, pos);
@ -887,7 +903,7 @@ pub fn get_next_token(
))), ))),
start_pos, start_pos,
)), )),
('-', _) if state.can_be_unary => return Some((Token::UnaryMinus, start_pos)), ('-', _) if !state.non_unary => return Some((Token::UnaryMinus, start_pos)),
('-', _) => return Some((Token::Minus, start_pos)), ('-', _) => return Some((Token::Minus, start_pos)),
('*', '=') => { ('*', '=') => {
@ -903,7 +919,7 @@ pub fn get_next_token(
let mut comment = if state.include_comments { let mut comment = if state.include_comments {
"//".to_string() "//".to_string()
} else { } else {
Default::default() String::new()
}; };
while let Some(c) = stream.get_next() { while let Some(c) = stream.get_next() {
@ -930,7 +946,7 @@ pub fn get_next_token(
let mut comment = if state.include_comments { let mut comment = if state.include_comments {
"/*".to_string() "/*".to_string()
} else { } else {
Default::default() String::new()
}; };
scan_comment(stream, state, pos, &mut comment); scan_comment(stream, state, pos, &mut comment);
@ -1103,7 +1119,7 @@ pub fn get_next_token(
} }
} }
/// An type that implements the `InputStream` trait. /// A type that implements the `InputStream` trait.
/// Multiple charaacter streams are jointed together to form one single stream. /// Multiple charaacter streams are jointed together to form one single stream.
pub struct MultiInputsStream<'a> { pub struct MultiInputsStream<'a> {
/// The input character streams. /// The input character streams.
@ -1157,11 +1173,7 @@ impl<'a> Iterator for TokenIterator<'a> {
type Item = (Token, Position); type Item = (Token, Position);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
get_next_token(&mut self.stream, &mut self.state, &mut self.pos).map(|x| { get_next_token(&mut self.stream, &mut self.state, &mut self.pos)
// Save the last token's state
self.state.can_be_unary = x.0.is_next_unary();
x
})
} }
} }
@ -1170,7 +1182,7 @@ pub fn lex<'a>(input: &'a [&'a str], max_string_size: usize) -> TokenIterator<'a
TokenIterator { TokenIterator {
state: TokenizeState { state: TokenizeState {
max_string_size, max_string_size,
can_be_unary: true, non_unary: false,
comment_level: 0, comment_level: 0,
end_with_none: false, end_with_none: false,
include_comments: false, include_comments: false,