pub mod ast;
mod builder;
mod common;
pub mod error;
pub mod grammar;
pub mod lexer;
pub mod load_grammar;
mod macros;
pub mod parser;
pub mod parser_frontends;
pub mod preclude;
mod transform;
use crate::ast::AST;
pub use crate::builder::GrammarBuilder;
use crate::grammar::Algorithm;
use crate::lexer::Token;
use crate::load_grammar::load_grammar;
use error::ParserError;
use std::sync::Arc;
#[derive(Clone, Debug)]
pub enum Ambiguity {
Resolve,
Explicit,
}
#[derive(Clone, Debug)]
pub enum LexerMode {
Basic,
Dynamic,
Scannerless,
}
#[derive(Debug, Clone)]
pub struct ParserOption {
pub start: String,
pub algorithm: Algorithm,
pub ambiguity: Ambiguity,
pub lexer_mode: LexerMode,
pub debug: bool,
}
impl Default for ParserOption {
fn default() -> Self {
Self {
start: "start".to_string(),
algorithm: Algorithm::Earley,
ambiguity: Ambiguity::Resolve,
lexer_mode: LexerMode::Basic,
debug: false,
}
}
}
pub struct Swiftlet {
grammar_builder: GrammarBuilder,
}
impl Swiftlet {
pub fn from_string(
grammar: &str,
parser_option: Arc<ParserOption>,
) -> Result<Self, ParserError> {
#[cfg(feature = "debug")]
let _grammar = match load_grammar(grammar, parser_option.clone()) {
Ok(g) => g,
Err(err) => return Err(err),
};
#[cfg(not(feature = "debug"))]
let _grammar = match load_grammar(grammar) {
Ok(g) => g,
Err(err) => return Err(err),
};
Ok(Self {
grammar_builder: GrammarBuilder::new(_grammar, parser_option.clone()),
})
}
pub fn from_file(file: String, parser_option: Arc<ParserOption>) -> Result<Self, ParserError> {
let content = std::fs::read_to_string(file).unwrap();
Self::from_string(content.as_str(), parser_option)
}
pub fn parse(&self, text: &str) -> Result<AST, ParserError> {
self.grammar_builder.parse(text)
}
pub fn tokens(&self, text: &str) -> Vec<Token> {
self.grammar_builder.tokens(text)
}
pub fn print_tokens(&self, text: &str) {
for token in self.tokens(text) {
println!("{}", format_token_debug(&token));
}
}
}
fn format_token_debug(token: &Token) -> String {
format!(
"{} -> {:?} @ {}..{}",
token.get_terminal(),
token.word(),
token.get_start(),
token.get_end()
)
}