Working
This commit is contained in:
124
src/parsing.rs
Normal file
124
src/parsing.rs
Normal file
@ -0,0 +1,124 @@
|
||||
use std::path::Path;
|
||||
|
||||
use winnow::Parser;
|
||||
use winnow::Result;
|
||||
use winnow::ascii::alphanumeric0;
|
||||
use winnow::ascii::multispace0;
|
||||
use winnow::combinator::alt;
|
||||
use winnow::combinator::delimited;
|
||||
use winnow::combinator::opt;
|
||||
use winnow::combinator::separated;
|
||||
use winnow::combinator::seq;
|
||||
use winnow::error::ContextError;
|
||||
|
||||
use crate::ast::Body;
|
||||
use crate::ast::Clause;
|
||||
use crate::ast::Module;
|
||||
use crate::ast::Predicate;
|
||||
|
||||
pub fn predicate_parse(input: &mut &str) -> Result<Predicate>
|
||||
{
|
||||
let ident = alphanumeric0.parse_next(input)?;
|
||||
|
||||
// Check if output is a variable
|
||||
if ident.chars().next().is_some_and(|char| char.is_uppercase())
|
||||
{
|
||||
Ok(Predicate::Variable(String::from(ident)))
|
||||
}
|
||||
else
|
||||
{
|
||||
let arguments = delimited(
|
||||
("(", multispace0),
|
||||
separated(1.., predicate_parse, (multispace0, ",", multispace0)),
|
||||
(multispace0, ")"),
|
||||
)
|
||||
.parse_next(input)
|
||||
.unwrap_or(Vec::new());
|
||||
Ok(Predicate::Fixed(String::from(ident), arguments))
|
||||
}
|
||||
}
|
||||
|
||||
fn body_parse_or(input: &mut &str) -> Result<Body>
|
||||
{
|
||||
separated(
|
||||
1..,
|
||||
alt((
|
||||
delimited("(", body_parse, ")"),
|
||||
predicate_parse.map(Body::Term),
|
||||
)),
|
||||
(multispace0, ";", multispace0),
|
||||
)
|
||||
.map(Body::Or)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
pub fn body_parse(input: &mut &str) -> Result<Body>
|
||||
{
|
||||
// Parse and
|
||||
separated(1.., body_parse_or, (multispace0, ",", multispace0))
|
||||
.map(Body::And)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
pub fn clause_parse(input: &mut &str) -> Result<Clause>
|
||||
{
|
||||
seq! {
|
||||
Clause
|
||||
{
|
||||
head: predicate_parse,
|
||||
body: opt((multispace0, ":-", multispace0, body_parse).map(|(_, _, _, b)| b)),
|
||||
_: multispace0,
|
||||
_: "."
|
||||
}
|
||||
}
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
pub fn module_parse(input: &mut &str) -> Result<Module>
|
||||
{
|
||||
let _: Result<&str, ContextError> = multispace0.parse_next(input);
|
||||
separated(0.., clause_parse, multispace0)
|
||||
.map(|clauses| Module { clauses })
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
impl<T> From<T> for Module
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn from(value: T) -> Self
|
||||
{
|
||||
let mut str: &str = value.as_ref();
|
||||
module_parse.parse_next(&mut str).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Module
|
||||
{
|
||||
pub fn parse_from_file<P: AsRef<Path>>(path: P) -> Self
|
||||
{
|
||||
std::fs::read_to_string(path).unwrap().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for Predicate
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn from(value: T) -> Self
|
||||
{
|
||||
let mut str: &str = value.as_ref();
|
||||
predicate_parse.parse_next(&mut str).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for Body
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn from(value: T) -> Self
|
||||
{
|
||||
let mut str: &str = value.as_ref();
|
||||
body_parse.parse_next(&mut str).unwrap()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user