use parol_runtime::{FileSource, Token, TokenStream};
use scnr2::scanner;
use std::borrow::Cow;
use std::cell::RefCell;
use std::path::{Path, PathBuf};
scanner!(
StringScanner {
mode INITIAL {
token r"\r\n|\r|\n" => 1; token r"[\s--\r\n]+" => 2; token r"//.*(\r\n|\r|\n)?" => 3; token r"/\*([.\r\n--*]|\*[^/])*\*/" => 4; token r"[a-zA-Z_]\w*" => 5; token r"\u{22}" => 9; token "." => 10; on 9 enter STRING; }
mode STRING {
token r"\u{5c}[\u{22}\u{5c}bfnt]" => 6; token r"\u{5c}[\s^\n\r]*\r?\n" => 7; token r"[^\u{22}\u{5c}]+" => 8; token r"\u{22}" => 9; token "." => 10; on 9 enter INITIAL; }
}
);
const MAX_K: usize = 1;
const INPUT: &str = r#"Id1
"1. String"
Id2
"2. \"String\t\" with \
escaped newline"
"3. String \nwith newline""#;
fn init() {
let _ = env_logger::builder().is_test(true).try_init();
}
fn print_skip_tokens<F: Fn(char) -> Option<usize> + Clone>(
token_stream: &RefCell<TokenStream<'_, F>>,
) {
token_stream
.borrow_mut()
.take_skip_tokens()
.into_iter()
.for_each(|t| println!("Skipping {t:?}"));
}
#[test]
fn scanner_switch_and_named_source() {
init();
let file_name: Cow<'static, Path> = Cow::Owned(PathBuf::default());
let scanner = string_scanner::StringScanner::new();
let stream = RefCell::new(
TokenStream::new(
INPUT,
file_name,
scanner.scanner_impl.clone(),
&string_scanner::StringScanner::match_function,
MAX_K,
)
.unwrap(),
);
eprintln!("'{INPUT:#?}'");
for (i, c) in INPUT.chars().enumerate() {
eprintln!("{i:2}: {}", c.escape_debug());
}
eprintln!();
assert_eq!(stream.borrow().current_scanner_index(), 0);
let mut prev_tok = Token::default();
let mut token_count = 0;
while !stream.borrow().all_input_consumed() {
let tok = stream.borrow_mut().lookahead(0).unwrap();
println!("{:w$}: {:?}", token_count, tok, w = 3);
let file_source = FileSource::from_stream(&stream.borrow());
let source_span: std::ops::Range<usize> = (&tok).into();
let span_contents: &str = &file_source.input.as_str()[source_span.clone()];
assert_eq!(span_contents, tok.text());
assert_eq!(span_contents, &INPUT[source_span]);
print_skip_tokens(&stream);
stream.borrow_mut().consume().unwrap();
token_count += 1;
prev_tok = tok;
}
assert_eq!(stream.borrow().current_scanner_index(), 0);
assert_eq!(prev_tok.text(), "\"");
assert_eq!(prev_tok.location.start_line, 7);
assert_eq!(prev_tok.location.start_column, 26);
}