pddl_ish_parser/parser/
problem_parser.rs1use nom::bytes::complete::take_until;
2use nom::{
3 bytes::complete::tag,
4 character::complete::{multispace0, multispace1},
5 sequence::{delimited, preceded},
6};
7use regex::Regex;
8
9use super::action::parse_actions;
10use super::error_context::get_error_context;
11use super::object::parse_objects;
12use crate::models::parser_error::ParserError;
13use crate::models::problem::Problem;
14
15pub fn parse_problem(original_input: &str) -> Result<(String, Problem), ParserError> {
17 let re = Regex::new(r";.*").unwrap();
19 let input_no_comments = re.replace_all(original_input, "").to_string();
20 let input = input_no_comments.as_str();
22
23 let (input, _) = tag("(define (problem ")(input).map_err(|err: nom::Err<nom::error::Error<&str>>| ParserError {
24 description: format!("{}", err),
25 code: get_error_context(input),
26 })?;
27 let (input, name) = take_until(")")(input).map_err(|err: nom::Err<nom::error::Error<&str>>| ParserError {
28 description: format!("{}", err),
29 code: get_error_context(input),
30 })?;
31 let (input, _) = tag(")")(input).map_err(|err: nom::Err<nom::error::Error<&str>>| ParserError {
32 description: format!("{}", err),
33 code: get_error_context(input),
34 })?;
35 let (_, domain) = parse_problem_domain(input)?;
36 let (_, objects) = parse_objects(&input_no_comments)?;
38 let (_, actions) = parse_actions(&input_no_comments)?;
40 Ok((
43 input_no_comments.clone(),
44 Problem {
45 name: name.to_string().trim().to_owned(),
46 domain,
47 objects,
48 init: vec![],
49 goal: vec![],
50 actions,
51 },
52 ))
53}
54
55pub fn parse_problem_domain(input: &str) -> Result<(&str, String), ParserError> {
56 delimited(
57 multispace0::<&str, ParserError>,
58 preceded(
59 tag("(:domain"),
60 delimited(multispace1::<&str, ParserError>, take_until(")"), tag(")")),
61 ),
62 multispace0::<&str, ParserError>,
63 )(input)
64 .map(|(next_input, domain)| (next_input, domain.to_string()))
65 .map_err(|err| ParserError {
66 description: format!("{}", err),
67 code: get_error_context(input),
68 })
69}