web_automaton.rs (3719B)
1 use std::{error::Error, fmt::Display}; 2 3 use wasm_bindgen::prelude::*; 4 5 use crate::{ 6 dfa::Transition as DFATransition, 7 graph_enfa::{GraphENFA, Transition as GraphENFATransition}, 8 nfa::{Transition as NFATransition, NFA}, 9 regex::Regex, 10 Automaton, AutomatonError, Dot, Encodable, 11 }; 12 13 #[wasm_bindgen] 14 extern "C" { 15 #[wasm_bindgen(js_namespace = console)] 16 fn log(s: &str); 17 18 #[wasm_bindgen(js_namespace = console)] 19 fn error(s: &str); 20 } 21 22 #[wasm_bindgen] 23 #[derive(Debug)] 24 pub struct WebAutomatonError { 25 automaton_error: AutomatonError, 26 } 27 28 impl Display for WebAutomatonError { 29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 30 write!(f, "{}", self.automaton_error.to_string()) 31 } 32 } 33 34 impl Error for WebAutomatonError {} 35 36 impl From<AutomatonError> for WebAutomatonError { 37 fn from(e: AutomatonError) -> Self { 38 WebAutomatonError { automaton_error: e } 39 } 40 } 41 42 #[wasm_bindgen] 43 impl WebAutomatonError { 44 #[wasm_bindgen] 45 pub fn to_string(&self) -> String { 46 ToString::to_string(self) 47 } 48 } 49 50 #[wasm_bindgen] 51 pub struct WebRegex { 52 regex_string: String, 53 regex: Regex, 54 enfa: GraphENFA, 55 nfa: NFA, 56 } 57 58 impl Display for WebRegex { 59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 60 writeln!(f, "Regex string: {}", self.regex_string)?; 61 writeln!(f, "Parsed regex: {:?}", self.regex.parsed)?; 62 writeln!(f, "ENFA: {}", self.enfa)?; 63 writeln!(f, "NFA: {}", self.nfa)?; 64 writeln!(f, "DFA: {}", self.regex.automaton) 65 } 66 } 67 68 impl Automaton for WebRegex { 69 fn accepts(&self, input: &str) -> bool { 70 self.regex.automaton.accepts(input) 71 } 72 } 73 74 #[wasm_bindgen] 75 impl WebRegex { 76 #[wasm_bindgen(constructor)] 77 pub fn new(regex: &str) -> Result<WebRegex, WebAutomatonError> { 78 let (mut graph_enfa, current_state) = GraphENFA::new(); 79 let re = Regex::parse(regex)?; 80 let parse_tree = re.parsed.clone(); 81 let final_state = graph_enfa.add_non_terminal(parse_tree, current_state)?; 82 graph_enfa.set_state_acceptance(final_state, true)?; 83 84 Ok(WebRegex { 85 regex_string: regex.to_owned(), 86 regex: re, 87 enfa: graph_enfa.clone(), 88 nfa: graph_enfa.as_enfa()?.as_nfa(), 89 }) 90 } 91 92 #[wasm_bindgen] 93 pub fn accepts(&self, input: &str) -> bool { 94 Automaton::accepts(self, input) 95 } 96 97 #[wasm_bindgen] 98 pub fn regex_string(&self) -> String { 99 self.regex_string.clone() 100 } 101 102 #[wasm_bindgen] 103 pub fn regex_to_string(&self) -> String { 104 self.regex.to_string() 105 } 106 107 #[wasm_bindgen] 108 pub fn enfa_to_string(&self) -> String { 109 self.enfa.to_string() 110 } 111 112 #[wasm_bindgen] 113 pub fn nfa_to_string(&self) -> String { 114 self.nfa.to_string() 115 } 116 117 #[wasm_bindgen] 118 pub fn dfa_to_string(&self) -> String { 119 self.regex.automaton.to_string() 120 } 121 122 #[wasm_bindgen] 123 pub fn enfa_dot(&self) -> Result<String, WebAutomatonError> { 124 (&self.enfa) 125 .try_into() 126 .map(|d: Dot<GraphENFATransition>| d.to_string()) 127 .map_err(|e| e.into()) 128 .into() 129 } 130 131 #[wasm_bindgen] 132 pub fn nfa_dot(&self) -> Result<String, WebAutomatonError> { 133 (&self.nfa) 134 .try_into() 135 .map(|d: Dot<NFATransition>| d.to_string()) 136 .map_err(|e| e.into()) 137 .into() 138 } 139 140 #[wasm_bindgen] 141 pub fn dfa_dot(&self) -> Result<String, WebAutomatonError> { 142 (&self.regex.automaton) 143 .try_into() 144 .map(|d: Dot<DFATransition>| d.to_string()) 145 .map_err(|e| e.into()) 146 .into() 147 } 148 }