1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
extern crate csv;
use std::error::Error;
use std::fmt::Debug;
#[derive(Debug)]
pub struct Config {
input: String,
states: Vec<u32>,
inputs: Vec<char>,
transition_table: Vec<Vec<u32>>,
start_state: u32,
final_states: Vec<u32>,
}
impl Config {
pub fn new (args: Vec<String>) -> Result<Config, Box<Error>> {
let input = args[1].to_string();
let mut inputs = Vec::new();
let mut states = Vec::new();
let start_state: u32 = args[2].parse()?;
let mut final_states = Vec::new();
let final_states_path = args[4].to_string();
let mut transition_table: Vec<Vec<u32>> = Vec::new();
let transition_table_path = args[3].to_string();
let mut final_states_reader = csv::ReaderBuilder::new()
.has_headers(false)
.from_path(final_states_path)?;
for record in final_states_reader.records() {
for final_state in record?.iter() {
final_states.push(final_state.trim().parse()?);
}
}
let mut transition_table_reader = csv::ReaderBuilder::new()
.has_headers(true)
.from_path(transition_table_path)?;
for field in transition_table_reader.headers()?.iter().skip(1) {
let input: char = field.trim().parse()?;
inputs.push(input)
}
for record in transition_table_reader.records() {
let mut row = Vec::new();
for delta in record?.iter() {
row.push(delta.trim().parse()?)
}
states.push(row.remove(0));
transition_table.push(row.clone());
}
Ok(Config{ input,states, inputs, transition_table, start_state, final_states })
}
}
pub fn run(config: &Config) -> Result<bool, Box<Error>> {
let mut present_state: &u32 = &config.start_state;
for symbol in config.input.chars() {
let input_index = find(symbol, &config.inputs).unwrap_or_else(|| { panic!("Wrong inputs") });
let state_index = find(*present_state, &config.states).unwrap_or_else(|| { panic!("Wrong states"); });
present_state = config.transition_table.get(state_index).unwrap().get(input_index).unwrap();
}
Ok(config.final_states.contains(present_state))
}
fn find<T: PartialEq+Debug>(key: T, vector: &Vec<T>) -> Option<usize> {
for (i, element) in vector.iter().enumerate() {
if key == *element {
return Some(i);
}
}
None
}