use self::ast::{Items, Replace};
use std::error::Error;
pub mod ast;
mod parsecommand;
mod parsereplacement;
lalrpop_mod!(reg, "/regexparser/reg.rs");
lalrpop_mod!(set, "/regexparser/set.rs");
lalrpop_mod!(pub query, "/regexparser/query.rs");
lalrpop_mod!(location, "/regexparser/location.rs");
pub fn parse(text: &str) -> Result<ast::Replace, Box<dyn Error>> {
let ru = parsecommand::parse(text)?;
let location = location::LocationParser::new()
.parse(&ru.location)
.map_err(|_| "Failed to parse location")?;
let find = reg::RegexParser::new()
.parse(&ru.find)
.map_err(|_| "Failed to parse regex")?;
let replace = parsereplacement::parse(&ru.replace)?;
Ok(Replace {
location,
find,
replace: Box::new(replace),
global: ru.global,
})
}
pub fn parse_set(s: String) -> Box<Items> {
set::ItemsParser::new().parse(&s).unwrap()
}
#[test]
fn parsing_reg() {
assert!(reg::RegexParser::new().parse("a|b|c").is_ok());
assert!(reg::RegexParser::new().parse("abc").is_ok());
assert!(reg::RegexParser::new().parse("ab-c").is_ok());
assert!(reg::RegexParser::new().parse("a=bc").is_ok());
assert!(reg::RegexParser::new().parse("\\-").is_ok());
assert!(reg::RegexParser::new().parse("[a-c]").is_ok());
assert!(reg::RegexParser::new().parse("\\n").is_ok());
assert!(reg::RegexParser::new().parse("[[name=x,type=int]]").is_ok());
assert!(reg::RegexParser::new().parse("[[functions]]").is_ok());
assert!(reg::RegexParser::new().parse("a|b|(").is_err());
assert!(reg::RegexParser::new().parse("[[]]").is_err());
}
#[test]
fn parsing_set() {
assert!(set::ItemsParser::new().parse("abc").is_ok());
assert!(set::ItemsParser::new().parse("a-c").is_ok());
assert!(set::ItemsParser::new().parse("abc-d").is_ok());
assert!(set::ItemsParser::new().parse("ab-cd").is_ok());
assert!(set::ItemsParser::new().parse("\\n").is_ok());
assert!(set::ItemsParser::new().parse("name=x,type=int").is_ok());
assert!(set::ItemsParser::new().parse("functions").is_ok());
assert!(set::ItemsParser::new().parse("fun").is_ok());
assert!(set::ItemsParser::new().parse("abc-").is_err());
}
#[test]
fn parsing_query() {
assert!(query::QueriesParser::new().parse("name=x").is_ok());
assert!(query::QueriesParser::new().parse("name=x,type=int").is_ok());
assert!(query::QueriesParser::new().parse("functions").is_ok());
assert!(query::QueriesParser::new().parse("fun").is_err());
}
#[test]
fn parsing_location() {
assert!(location::LocationParser::new().parse("<../../../>").is_ok());
assert!(location::LocationParser::new().parse("{function}").is_ok());
assert!(location::LocationParser::new().parse("{function}|l1-5").is_ok());
assert!(location::LocationParser::new().parse("{function}&l1-5").is_ok());
assert!(location::LocationParser::new().parse("^{function}|l1-5").is_ok());
assert!(location::LocationParser::new().parse("(^{function}|l1-5)").is_ok());
assert!(location::LocationParser::new().parse("l0-2").is_ok());
assert!(location::LocationParser::new().parse("c0-2").is_ok());
assert!(location::LocationParser::new().parse("%").is_ok());
assert!(location::LocationParser::new().parse("%:").is_err());
}
#[test]
fn parsing_entire() {
assert!(parse("%s/westoff/Westhoff").is_err());
assert!(parse("%s/westoff/Westhoff/").is_ok());
assert!(parse("<mod.rs>s/jon/John/g").is_ok());
}