feat: Scanning of nested comments
This commit is contained in:
parent
14c1b6f8d8
commit
9b75323dc9
@ -35,7 +35,7 @@ fn scan_any_except_new_line(
|
|||||||
pub fn scan_multiline(chars: &Vec<char>, start_pos: usize) -> LexResult {
|
pub fn scan_multiline(chars: &Vec<char>, start_pos: usize) -> LexResult {
|
||||||
match multiline_impl(chars, start_pos + 2) {
|
match multiline_impl(chars, start_pos + 2) {
|
||||||
Some((value, next_position)) => LexResult::Some(
|
Some((value, next_position)) => LexResult::Some(
|
||||||
Token::new_multiline_comment(value, start_pos),
|
Token::new_multiline_comment(value.iter().collect(), start_pos),
|
||||||
next_position,
|
next_position,
|
||||||
),
|
),
|
||||||
None => {
|
None => {
|
||||||
@ -49,17 +49,39 @@ pub fn scan_multiline(chars: &Vec<char>, start_pos: usize) -> LexResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn multiline_impl(chars: &Vec<char>, start_pos: usize) -> Option<(String, usize)> {
|
fn multiline_impl(chars: &Vec<char>, start_pos: usize) -> Option<(Vec<char>, usize)> {
|
||||||
let mut current_position = start_pos;
|
let mut current_position = start_pos;
|
||||||
let mut result = Vec::<char>::new();
|
let mut result = Vec::<char>::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match chars.get(current_position) {
|
match chars.get(current_position) {
|
||||||
Some('/') => {
|
Some('/') => {
|
||||||
// TODO: Check for a nested comment instead of
|
|
||||||
// appending
|
match chars.get(current_position + 1) {
|
||||||
|
Some('*') => {
|
||||||
|
// Scan nested comment
|
||||||
|
let (mut nested, next_position) = match multiline_impl(chars, current_position + 2)
|
||||||
|
{
|
||||||
|
Some(v) => v,
|
||||||
|
None => {
|
||||||
|
// The nested comment is not closed.
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
result.push('/');
|
result.push('/');
|
||||||
current_position += 1;
|
result.push('*');
|
||||||
|
result.append(&mut nested);
|
||||||
|
result.push('*');
|
||||||
|
result.push('/');
|
||||||
|
current_position = next_position;
|
||||||
|
}
|
||||||
|
Some(c) => {
|
||||||
|
// Append both characters
|
||||||
|
result.push('/');
|
||||||
|
result.push(*c);
|
||||||
|
}
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some('*') => {
|
Some('*') => {
|
||||||
// Check for the end of a comment
|
// Check for the end of a comment
|
||||||
@ -67,7 +89,7 @@ fn multiline_impl(chars: &Vec<char>, start_pos: usize) -> Option<(String, usize)
|
|||||||
Some('/') => {
|
Some('/') => {
|
||||||
// Create and return the token,
|
// Create and return the token,
|
||||||
// ignoring the `*/`
|
// ignoring the `*/`
|
||||||
return Some((result.iter().collect(), current_position + 2));
|
return Some((result, current_position + 2));
|
||||||
}
|
}
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
// Append both and continue
|
// Append both and continue
|
||||||
@ -87,7 +109,6 @@ fn multiline_impl(chars: &Vec<char>, start_pos: usize) -> Option<(String, usize)
|
|||||||
current_position += 1;
|
current_position += 1;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Throw an error
|
|
||||||
// TODO: Also return the position where this token ends,
|
// TODO: Also return the position where this token ends,
|
||||||
// to display better error messages.
|
// to display better error messages.
|
||||||
// Requires LexError to implement an end_position field
|
// Requires LexError to implement an end_position field
|
||||||
@ -231,4 +252,22 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shoud_scan_nested_multiline_comments() {
|
||||||
|
let input = str_to_vec("/* my /* comment */ */");
|
||||||
|
|
||||||
|
let result = scan_multiline(&input, 0);
|
||||||
|
match result {
|
||||||
|
LexResult::Some(t, next) => {
|
||||||
|
assert_eq!(22, next);
|
||||||
|
assert_eq!(" my /* comment */ ", t.value);
|
||||||
|
assert_eq!(0, t.position);
|
||||||
|
assert_eq!(TokenType::MultilineComment, t.token_type);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("Expected a multine comment")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user