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
use std::hash::{Hash, Hasher};
use murmur3::murmur3_32::MurmurHasher;
use crate::int_stream::IntStream;
use crate::lexer::Lexer;
use crate::lexer_action::LexerAction;
use crate::lexer_action::LexerAction::LexerIndexedCustomAction;
#[derive(Clone, Eq, PartialEq, Debug)]
pub(crate) struct LexerActionExecutor {
cached_hash: u64,
lexer_actions: Vec<LexerAction>,
}
impl Hash for LexerActionExecutor {
fn hash<H: Hasher>(&self, state: &mut H) { state.write_u64(self.cached_hash) }
}
impl LexerActionExecutor {
pub(crate) fn new(lexer_actions: Vec<LexerAction>) -> LexerActionExecutor {
let cached_hash = lexer_actions
.iter()
.fold(MurmurHasher::default(), |mut acc, x| {
x.hash(&mut acc);
acc
})
.finish();
LexerActionExecutor {
lexer_actions,
cached_hash,
}
}
pub(crate) fn new_copy_append(
old: Option<&Self>,
lexer_action: LexerAction,
) -> LexerActionExecutor {
let mut new = old
.cloned()
.unwrap_or_else(|| LexerActionExecutor::new(Vec::new()));
new.lexer_actions.push(lexer_action);
new
}
pub fn fix_offset_before_match(mut self, offset: isize) -> LexerActionExecutor {
for action in self.lexer_actions.iter_mut() {
match action {
LexerAction::LexerIndexedCustomAction { .. } => {}
_ => {
if action.is_position_dependent() {
*action = LexerIndexedCustomAction {
offset,
action: Box::new(action.clone()),
};
}
}
}
}
self
}
pub fn execute<'input>(&self, lexer: &mut impl Lexer<'input>, start_index: isize) {
let mut requires_seek = false;
let stop_index = lexer.input().index();
for action in self.lexer_actions.iter() {
if let LexerAction::LexerIndexedCustomAction { offset, .. } = action {
lexer.input().seek(start_index + offset);
requires_seek = start_index + offset != stop_index;
} else if action.is_position_dependent() {
lexer.input().seek(stop_index);
requires_seek = false
}
action.execute(lexer);
}
if requires_seek {
lexer.input().seek(stop_index);
}
}
}