add multi token : contains

This commit is contained in:
Synth Magic 2022-06-11 21:07:21 +08:00
parent abb78a0067
commit f584119b70
2 changed files with 26 additions and 20 deletions

View File

@ -1 +1 @@
pub mod parser; pub mod parser;

View File

@ -3,6 +3,7 @@ use colorful::*;
use rand::prelude::*; use rand::prelude::*;
use std::fs::*; use std::fs::*;
use std::iter::repeat_with; use std::iter::repeat_with;
const CONTROLS: [char; 3] = ['\n', '\r', '\t'];
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Parser { pub struct Parser {
pub file: Option<String>, pub file: Option<String>,
@ -25,7 +26,7 @@ impl Parser {
} }
} }
pub fn next_token(&mut self) -> Option<Vec<&str>> { pub fn next_token(&mut self) -> Option<Vec<&str>> {
if self.position == (self.context.len() - 1) { if (self.position) >= (self.context.len() - 1) {
return None; return None;
} }
let substr: &str = self let substr: &str = self
@ -45,8 +46,8 @@ impl Parser {
.collect::<Vec<&str>>(), .collect::<Vec<&str>>(),
) )
} }
fn is_vailid_token(&self, token: &str) -> bool { pub fn is_vailid_token(&self, token: &str) -> bool {
self.parse(vec![token]).is_ok() || token.parse::<f64>().is_ok() self.parse(vec![token]).is_ok() || token.parse::<f64>().is_ok() || CONTROLS.iter().any(|&x| token.contains(x))
} }
pub fn parse(&self, tokens: Vec<&str>) -> Result<String> { pub fn parse(&self, tokens: Vec<&str>) -> Result<String> {
if tokens.len() != 1 { if tokens.len() != 1 {
@ -73,11 +74,15 @@ impl Parser {
.collect::<String>() .collect::<String>()
}); });
} }
"string" => Ok( "string" => Ok(repeat_with(|| {
repeat_with(|| thread_rng().gen_range(10_u8..126_u8) as char) if random::<u16>() % 26 == 0 {
.take(random::<u16>() as usize) CONTROLS[thread_rng().gen_range(0..=2)]
.collect::<String>(), } else {
), thread_rng().gen_range(32_u8..=126_u8) as char
}
})
.take(random::<u16>() as usize)
.collect::<String>()),
"char" => Ok(random::<char>().to_string()), "char" => Ok(random::<char>().to_string()),
_ => bail!( _ => bail!(
"{}", "{}",
@ -105,19 +110,20 @@ impl Parser {
) )
.to_string()); .to_string());
} }
_ => { "contains" => {
if !self.is_vailid_token(i) { if tokens[0] != "string" {
ret = Err(anyhow!( ret = Err(anyhow!("{}\n{}",format!("Parse error at position {} : unable to confine `contains` for current type",self.position + 1).color(Color::Red).bold(),"note : the multi token `contains` is only valid for type string".color(Color::Blue)));
"{}", } else {
format!( let mut str = self.parse(vec!["string"]).unwrap();
"failed to parse at position {} : read undeclared tokens", if !str.contains(tokens[c + 1]) {
self.position + 1 str.insert_str(thread_rng().gen_range(0..str.len()), tokens[c + 1]);
) }
.color(Color::Red) ret = Ok(str);
.bold()
));
} }
} }
_ => {
}
} }
} }
ret ret