enfa.rs (1628B)
1 use automaton::{dfa::DFA, enfa::ENFA, Automaton, Encodable, FiniteStateAutomaton}; 2 use std::{env, error::Error, fmt::Display, fs}; 3 4 #[derive(Debug)] 5 struct CommandLineError { 6 reason: String, 7 } 8 9 impl Display for CommandLineError { 10 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 11 write!(f, "{}", self.reason) 12 } 13 } 14 15 impl CommandLineError { 16 fn cause(reason: &str) -> Self { 17 CommandLineError { 18 reason: reason.to_owned(), 19 } 20 } 21 } 22 23 impl Error for CommandLineError {} 24 25 fn usage(prog_name: &str) -> String { 26 format!("Usage: {prog_name} <NFA filename> <input string> <USE RAW NFA>") 27 } 28 29 fn main() -> Result<(), Box<dyn Error>> { 30 let args: Vec<String> = env::args().collect(); 31 32 if args.len() < 2 { 33 return Err(Box::new(CommandLineError::cause(&usage( 34 args.get(0).map_or("automaton", |s| s), 35 )))); 36 } 37 38 let enfa_json = fs::read_to_string(args.get(1).ok_or(CommandLineError::cause("Could not get filename from commandline args"))?)?; 39 let input_string = args 40 .get(2) 41 .map_or("".to_owned(), String::to_owned); 42 43 let enfa: ENFA = ENFA::parse(enfa_json.as_str())?; 44 let automaton: Box<dyn Automaton> = match args.get(3) { 45 None => { 46 println!("Converting to DFA"); 47 Box::new(DFA::convert(Box::new(enfa))?) 48 } 49 Some(_) => { 50 Box::new(enfa) 51 } 52 }; 53 println!("Automaton:\n{}", automaton); 54 println!("Running on the following input:\n\"{}\"", input_string); 55 println!("Accepts: {}", automaton.accepts(&input_string)); 56 57 Ok(()) 58 }