bf_derivatives_tools/
parser.rs1use super::grammar::*;
2use super::token::*;
3use regex;
4use regex::Regex;
5
6pub struct Parser {
7 code: String,
8}
9
10impl Parser {
11 pub fn new(code: &str) -> Self {
12 Self {
13 code: code.to_string(),
14 }
15 }
16
17 pub fn code(&self) -> String {
18 self.code.clone()
19 }
20
21 pub fn translate_to_bf(&mut self, from: &Grammar) {
22 let to = Grammar::bf();
23 self.translate(from, &to);
24 }
25
26 pub fn translate_from_bf(&mut self, to: &Grammar) {
27 let from = Grammar::bf();
28 self.translate(&from, &to);
29 }
30
31 pub fn translate(&mut self, from: &Grammar, to: &Grammar) {
32 let pattern = Parser::make_pattern(from);
33 let translated = Regex::new(&pattern)
34 .unwrap()
35 .find_iter(&self.code)
36 .map(|mat| {
37 let s = mat.as_str();
38 if s == from.rshift {
39 &to.rshift
40 } else if s == from.lshift {
41 &to.lshift
42 } else if s == from.inc {
43 &to.inc
44 } else if s == from.dec {
45 &to.dec
46 } else if s == from.write {
47 &to.write
48 } else if s == from.read {
49 &to.read
50 } else if s == from.loop_begin {
51 &to.loop_begin
52 } else if s == from.loop_end {
53 &to.loop_end
54 } else if s == " " || s == "\t" || s == "\n" || s == "\r\n" {
55 s
56 } else {
57 ""
58 }
59 })
60 .collect::<String>();
61 self.code = translated;
62 }
63
64 fn make_pattern(grammar: &Grammar) -> String {
65 let rshift = regex::escape(&grammar.rshift);
66 let lshift = regex::escape(&grammar.lshift);
67 let inc = regex::escape(&grammar.inc);
68 let dec = regex::escape(&grammar.dec);
69 let write = regex::escape(&grammar.write);
70 let read = regex::escape(&grammar.read);
71 let loop_begin = regex::escape(&grammar.loop_begin);
72 let loop_end = regex::escape(&grammar.loop_end);
73 format!(
74 "{}|{}|{}|{}|{}|{}|{}|{}|\x20|\t|\n|\r\n",
75 rshift, lshift, inc, dec, write, read, loop_begin, loop_end
76 )
77 }
78
79 pub fn parse(&self) -> Vec<Token> {
80 let tokens: Vec<_> = self
81 .code
82 .chars()
83 .map(|c| match c {
84 '>' => Token::RShift,
85 '<' => Token::LShift,
86 '+' => Token::Inc,
87 '-' => Token::Dec,
88 '.' => Token::Write,
89 ',' => Token::Read,
90 '[' => Token::LoopBegin,
91 ']' => Token::LoopEnd,
92 _ => Token::Ignore,
93 })
94 .collect();
95 tokens
96 }
97}