use super::dialect::parse as parse_dialect_opennars;
use crate::runtimes::TranslateError;
use anyhow::Result;
use nar_dev_utils::ResultBoost;
use narsese::lexical::{Narsese, Term};
use navm::{
cmd::Cmd,
output::{Operation, Output},
};
use regex::Regex;
pub fn input_translate(cmd: Cmd) -> Result<String> {
let content = match cmd {
Cmd::NSE(..) => cmd.tail(),
Cmd::CYC(n) => n.to_string(),
Cmd::VOL(n) => format!("*volume={n}"),
Cmd::REM { .. } => String::new(),
Cmd::EXI { .. } => "*exit".into(),
_ => return Err(TranslateError::UnsupportedInput(cmd).into()),
};
Ok(content)
}
pub fn output_translate(content_raw: String) -> Result<Output> {
let (head, tail) = content_raw.split_once(':').unwrap_or(("", &content_raw));
let tail = tail.trim();
let output = match &*head.to_uppercase() {
"IN" => Output::IN {
narsese: parse_narsese_opennars(head, tail)?,
content: content_raw,
},
"OUT" => {
Output::OUT {
narsese: parse_narsese_opennars(head, tail)?,
content_raw,
}
}
"ANSWER" => Output::ANSWER {
narsese: parse_narsese_opennars(head, tail)?,
content_raw,
},
"EXE" => Output::EXE {
operation: parse_operation_opennars(tail.trim_start()),
content_raw,
},
"ANTICIPATE" => Output::UNCLASSIFIED {
r#type: "ANTICIPATE".to_string(),
narsese: try_parse_narsese(tail)
.ok_or_run(|e| println!("【{head}】在解析Narsese「{tail}」时出现错误:{e}")),
content: content_raw,
},
"ERR" | "ERROR" => Output::ERROR {
description: content_raw,
},
"TERMINATED" | "EXITED" | "QUITTED" => Output::TERMINATED {
description: content_raw,
},
upper if !head.is_empty() && head == upper => Output::UNCLASSIFIED {
r#type: head.to_string(),
content: content_raw,
narsese: None,
},
_ => Output::OTHER {
content: content_raw,
},
};
Ok(output)
}
#[cfg(not(test))]
pub fn parse_narsese_opennars(head: &str, tail: &str) -> Result<Option<Narsese>> {
use nar_dev_utils::ResultBoost;
Ok(try_parse_narsese(tail)
.ok_or_run(|e| println!("【{head}】在解析Narsese「{tail}」时出现错误:{e}")))
}
#[cfg(test)]
pub fn parse_narsese_opennars(_: &str, tail: &str) -> Result<Option<Narsese>> {
Ok(Some(try_parse_narsese(tail)?))
}
pub fn parse_operation_opennars(tail: &str) -> Operation {
let r = Regex::new(r"(\$[0-9.;]+\$)\s*\^(\w+)\(\[(.*)\]\)=").unwrap();
let mut params = vec![];
let c = r.captures(tail);
let operator_name;
let params_str;
if let Some(c) = c {
operator_name = c[2].to_string();
params_str = &c[3];
for param in params_str.split(", ") {
match parse_term_from_operation(param) {
Ok(term) => params.push(term),
Err(e) => println!("【EXE】在解析Narsese时出现错误:{e}"),
}
}
} else {
operator_name = String::new();
}
Operation {
operator_name,
params,
}
}
fn parse_term_from_operation(term_str: &str) -> Result<Term> {
let parsed = parse_dialect_opennars(term_str)?;
parsed
.try_into_term()
.transform_err(TranslateError::error_anyhow)
}
fn try_parse_narsese(tail: &str) -> Result<Narsese> {
let narsese = parse_dialect_opennars(tail);
match narsese {
Ok(narsese) => Ok(narsese),
Err(err) => Err(TranslateError::from(err).into()),
}
}