use super::types::*;
use super::combinator::*;
use super::scheme::*;
use super::combinator::helpers::*;
use crate::diagnostics::Span;
use std::collections::HashMap;
pub struct ParserBuilder<'a> {
parsers: Vec<Box<dyn ParserCombinator<'a, ParsedValue<'a>>>>,
error_recovery: bool,
debug_mode: bool,
error_messages: HashMap<String, String>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ParsedValue<'a> {
String(&'a str),
Char(char),
Integer(i64),
Float(f64),
Boolean(bool),
List(Vec<ParsedValue<'a>>),
SExpression(SchemeSexp<'a>),
Raw(String),
}
impl<'a> Default for ParserBuilder<'a> {
fn default() -> Self {
Self::new()
}
}
impl<'a> ParserBuilder<'a> {
pub fn new() -> Self {
Self {
parsers: Vec::new(),
error_recovery: false,
debug_mode: false,
error_messages: HashMap::new(),
}
}
pub fn with_error_recovery(mut self) -> Self {
self.error_recovery = true;
self
}
pub fn with_debug(mut self) -> Self {
self.debug_mode = true;
self
}
pub fn with_error_message(mut self, context: String, message: String) -> Self {
self.error_messages.insert(context, message);
self
}
pub fn expect_string(mut self, expected: &'static str) -> Self {
let parser = Box::new(StringLiteralParser::new(expected));
self.parsers.push(parser);
self
}
pub fn expect_identifier(mut self) -> Self {
let parser = Box::new(IdentifierParser::new());
self.parsers.push(parser);
self
}
pub fn expect_number(mut self) -> Self {
let parser = Box::new(NumberParser::new());
self.parsers.push(parser);
self
}
pub fn expect_s_expression(mut self) -> Self {
let parser = Box::new(SExpressionParserWrapper::new());
self.parsers.push(parser);
self
}
pub fn skip_whitespace(mut self) -> Self {
let parser = Box::new(WhitespaceSkipParser::new());
self.parsers.push(parser);
self
}
pub fn maybe<T>(mut self, parser: T) -> Self
where
T: ParserCombinator<'a, ParsedValue<'a>> + 'static,
{
let parser = Box::new(OptionalParser::new(parser));
self.parsers.push(parser);
self
}
pub fn repeat<T>(mut self, parser: T) -> Self
where
T: ParserCombinator<'a, ParsedValue<'a>> + Clone + 'static,
{
let parser = Box::new(RepeatParser::new(parser));
self.parsers.push(parser);
self
}
pub fn build_and_parse(self, input: Input<'a>) -> ParseResult<'a, Vec<ParsedValue<'a>>> {
let mut results = Vec::new();
let mut remaining = input;
for parser in self.parsers {
match parser.parse(remaining) {
Ok((new_remaining, value)) => {
results.push(value);
remaining = new_remaining;
}
Err(err) => {
if self.error_recovery {
if self.debug_mode {
eprintln!("パーサーエラーが発生しました: {err:?}");
}
if let Some(space_pos) = remaining.find(' ') {
remaining = &remaining[space_pos..];
continue;
}
}
return Err(err);
}
}
}
Ok((remaining, results))
}
}
struct StringLiteralParser {
expected: &'static str,
}
impl StringLiteralParser {
fn new(expected: &'static str) -> Self {
Self { expected }
}
}
impl<'a> ParserCombinator<'a, ParsedValue<'a>> for StringLiteralParser {
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
let parser = tag(self.expected);
parser.parse(input).map(|(remaining, matched)| {
(remaining, ParsedValue::String(matched))
})
}
}
struct IdentifierParser;
impl IdentifierParser {
fn new() -> Self {
Self
}
}
impl<'a> ParserCombinator<'a, ParsedValue<'a>> for IdentifierParser {
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
let parser = SchemeParser::symbol();
parser.parse(input).map(|(remaining, symbol)| {
(remaining, ParsedValue::String(symbol))
})
}
}
struct NumberParser;
impl NumberParser {
fn new() -> Self {
Self
}
}
impl<'a> ParserCombinator<'a, ParsedValue<'a>> for NumberParser {
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
let parser = SchemeParser::number();
parser.parse(input).map(|(remaining, atom)| {
let value = match atom {
SchemeAtom::Integer(i) => ParsedValue::Integer(i),
SchemeAtom::Float(f) => ParsedValue::Float(f),
_ => ParsedValue::Raw(format!("{atom:?}")),
};
(remaining, value)
})
}
}
struct SExpressionParserWrapper;
impl SExpressionParserWrapper {
fn new() -> Self {
Self
}
}
impl<'a> ParserCombinator<'a, ParsedValue<'a>> for SExpressionParserWrapper {
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
let parser = SchemeParser::s_expression();
parser.parse(input).map(|(remaining, sexp)| {
(remaining, ParsedValue::SExpression(sexp))
})
}
}
struct WhitespaceSkipParser;
impl WhitespaceSkipParser {
fn new() -> Self {
Self
}
}
impl<'a> ParserCombinator<'a, ParsedValue<'a>> for WhitespaceSkipParser {
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
let parser = SchemeParser::skip_whitespace_and_comments();
parser.parse(input).map(|(remaining, _)| {
(remaining, ParsedValue::Raw("whitespace_skipped".to_string()))
})
}
}
struct OptionalParser<T> {
inner: T,
}
impl<T> OptionalParser<T> {
fn new(inner: T) -> Self {
Self { inner }
}
}
impl<'a, T> ParserCombinator<'a, ParsedValue<'a>> for OptionalParser<T>
where
T: ParserCombinator<'a, ParsedValue<'a>>,
{
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
match self.inner.parse(input) {
Ok(result) => Ok(result),
Err(_) => Ok((input, ParsedValue::Raw("none".to_string()))),
}
}
}
struct RepeatParser<T> {
inner: T,
}
impl<T> RepeatParser<T> {
fn new(inner: T) -> Self {
Self { inner }
}
}
impl<'a, T> ParserCombinator<'a, ParsedValue<'a>> for RepeatParser<T>
where
T: ParserCombinator<'a, ParsedValue<'a>> + Clone,
{
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
let mut results = Vec::new();
let mut remaining = input;
while let Ok((new_remaining, value)) = self.inner.parse(remaining) {
results.push(value);
remaining = new_remaining;
}
Ok((remaining, ParsedValue::List(results)))
}
}
pub struct ParserTemplates;
impl ParserTemplates {
pub fn scheme_function_definition<'a>() -> impl ParserCombinator<'a, ParsedValue<'a>> {
FunctionDefinitionParser::new()
}
pub fn scheme_variable_definition<'a>() -> impl ParserCombinator<'a, ParsedValue<'a>> {
VariableDefinitionParser::new()
}
pub fn scheme_if_expression<'a>() -> impl ParserCombinator<'a, ParsedValue<'a>> {
IfExpressionParser::new()
}
}
struct FunctionDefinitionParser;
impl FunctionDefinitionParser {
fn new() -> Self {
Self
}
}
impl<'a> ParserCombinator<'a, ParsedValue<'a>> for FunctionDefinitionParser {
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
let builder = ParserBuilder::new()
.expect_string("(")
.skip_whitespace()
.expect_string("define")
.skip_whitespace()
.expect_string("(")
.expect_identifier()
.skip_whitespace();
Ok((input, ParsedValue::Raw("function_definition".to_string())))
}
}
struct VariableDefinitionParser;
impl VariableDefinitionParser {
fn new() -> Self {
Self
}
}
impl<'a> ParserCombinator<'a, ParsedValue<'a>> for VariableDefinitionParser {
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
Ok((input, ParsedValue::Raw("variable_definition".to_string())))
}
}
struct IfExpressionParser;
impl IfExpressionParser {
fn new() -> Self {
Self
}
}
impl<'a> ParserCombinator<'a, ParsedValue<'a>> for IfExpressionParser {
fn parse(&self, input: Input<'a>) -> ParseResult<'a, ParsedValue<'a>> {
Ok((input, ParsedValue::Raw("if_expression".to_string())))
}
}
#[macro_export]
macro_rules! scheme_parser {
(expect $literal:literal) => {
ParserBuilder::new().expect_string($literal)
};
(identifier) => {
ParserBuilder::new().expect_identifier()
};
(number) => {
ParserBuilder::new().expect_number()
};
(s_expr) => {
ParserBuilder::new().expect_s_expression()
};
(skip_ws) => {
ParserBuilder::new().skip_whitespace()
};
}
#[cfg(test)]
#[allow(unused_imports, dead_code)]
mod tests {
use super::*;
#[test]
fn test_parser_builder_basic() {
let builder = ParserBuilder::new()
.expect_string("hello")
.skip_whitespace()
.expect_identifier();
let result = builder.build_and_parse("hello world");
assert!(result.is_ok());
let (remaining, values) = result.unwrap();
assert_eq!(values.len(), 3); assert_eq!(values[0], ParsedValue::String("hello"));
}
#[test]
fn test_parser_builder_with_error_recovery() {
let builder = ParserBuilder::new()
.with_error_recovery()
.with_debug()
.expect_string("missing")
.expect_identifier();
let result = builder.build_and_parse("hello world");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_number_parser() {
let parser = NumberParser::new();
let result = parser.parse("123");
assert!(result.is_ok());
let (remaining, value) = result.unwrap();
assert_eq!(remaining, "");
assert_eq!(value, ParsedValue::Integer(123));
}
#[test]
fn test_identifier_parser() {
let parser = IdentifierParser::new();
let result = parser.parse("hello-world");
assert!(result.is_ok());
let (remaining, value) = result.unwrap();
assert_eq!(remaining, "");
assert_eq!(value, ParsedValue::String("hello-world"));
}
#[test]
fn test_optional_parser() {
let inner = StringLiteralParser::new("optional");
let parser = OptionalParser::new(inner);
let result = parser.parse("optional");
assert!(result.is_ok());
let (remaining, value) = result.unwrap();
assert_eq!(remaining, "");
assert_eq!(value, ParsedValue::String("optional"));
let result = parser.parse("something_else");
assert!(result.is_ok());
let (remaining, value) = result.unwrap();
assert_eq!(remaining, "something_else");
assert_eq!(value, ParsedValue::Raw("none".to_string()));
}
#[test]
fn test_repeat_parser() {
let inner = StringLiteralParser::new("a");
let parser = RepeatParser::new(inner);
let result = parser.parse("aaab");
assert!(result.is_ok());
let (remaining, value) = result.unwrap();
assert_eq!(remaining, "b");
if let ParsedValue::List(items) = value {
assert_eq!(items.len(), 3);
for item in items {
assert_eq!(item, ParsedValue::String("a"));
}
} else {
panic!("Expected list value");
}
}
#[test]
fn test_scheme_parser_macro() {
let _parser = scheme_parser!(expect "hello");
let _parser = scheme_parser!(identifier);
let _parser = scheme_parser!(number);
let _parser = scheme_parser!(s_expr);
let _parser = scheme_parser!(skip_ws);
}
}