do_not_use_antlr_rust/
atn_config.rs

1use std::fmt::{Debug, Error, Formatter};
2use std::hash::{Hash, Hasher};
3use std::sync::Arc;
4
5use murmur3::murmur3_32::MurmurHasher;
6
7use crate::atn_config::ATNConfigType::LexerATNConfig;
8use crate::atn_state::{ATNState, ATNStateRef, ATNStateType};
9use crate::dfa::ScopeExt;
10use crate::lexer_action_executor::LexerActionExecutor;
11use crate::prediction_context::PredictionContext;
12use crate::semantic_context::SemanticContext;
13
14#[derive(Clone)]
15pub struct ATNConfig {
16    precedence_filter_suppressed: bool,
17    //todo since ATNState is immutable when we started working with ATNConfigs
18    // looks like it is possible to have usual reference here
19    state: ATNStateRef,
20    alt: isize,
21    //todo maybe option is unnecessary and PredictionContext::EMPTY would be enough
22    //another todo check arena alloc
23    context: Option<Arc<PredictionContext>>,
24    pub semantic_context: Box<SemanticContext>,
25    pub reaches_into_outer_context: isize,
26    pub(crate) config_type: ATNConfigType,
27}
28
29impl Eq for ATNConfig {}
30
31impl PartialEq for ATNConfig {
32    fn eq(&self, other: &Self) -> bool {
33        self.get_state() == other.get_state()
34            && self.get_alt() == other.get_alt()
35            && (Arc::ptr_eq(self.get_context().unwrap(), other.get_context().unwrap())
36                || self.get_context() == other.get_context())
37            && self.get_type() == other.get_type()
38            && self.semantic_context == other.semantic_context
39            && self.precedence_filter_suppressed == other.precedence_filter_suppressed
40    }
41}
42
43impl Hash for ATNConfig {
44    fn hash<H: Hasher>(&self, state: &mut H) {
45        state.write_i32(self.get_state() as i32);
46        state.write_i32(self.get_alt() as i32);
47        match self.get_context() {
48            None => state.write_i32(0),
49            Some(c) => c.hash(state),
50        }
51        self.semantic_context.hash(state);
52        if let LexerATNConfig {
53            lexer_action_executor,
54            passed_through_non_greedy_decision,
55        } = &self.config_type
56        {
57            state.write_i32(if *passed_through_non_greedy_decision {
58                1
59            } else {
60                0
61            });
62            match lexer_action_executor {
63                None => state.write_i32(0),
64                Some(ex) => ex.hash(state),
65            }
66        }
67    }
68}
69
70impl Debug for ATNConfig {
71    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
72        f.write_fmt(format_args!(
73            "({},{},[{}]",
74            self.state,
75            self.alt,
76            self.context.as_deref().unwrap()
77        ))?;
78        if self.reaches_into_outer_context > 0 {
79            f.write_fmt(format_args!(",up={}", self.reaches_into_outer_context))?;
80        }
81
82        f.write_str(")")
83    }
84}
85
86#[derive(Eq, PartialEq, Clone, Debug)]
87pub(crate) enum ATNConfigType {
88    BaseATNConfig,
89    LexerATNConfig {
90        lexer_action_executor: Option<Box<LexerActionExecutor>>,
91        passed_through_non_greedy_decision: bool,
92    },
93}
94
95impl ATNConfig {
96    pub(crate) fn get_lexer_executor(&self) -> Option<&LexerActionExecutor> {
97        match &self.config_type {
98            ATNConfigType::BaseATNConfig => None,
99            ATNConfigType::LexerATNConfig {
100                lexer_action_executor,
101                ..
102            } => lexer_action_executor.as_deref(),
103        }
104    }
105
106    pub fn default_hash(&self) -> u64 {
107        MurmurHasher::default().convert_with(|mut x| {
108            self.hash(&mut x);
109            x.finish()
110        })
111    }
112
113    pub fn new(
114        state: ATNStateRef,
115        alt: isize,
116        context: Option<Arc<PredictionContext>>,
117    ) -> ATNConfig {
118        ATNConfig {
119            precedence_filter_suppressed: false,
120            state,
121            alt,
122            context,
123            semantic_context: Box::new(SemanticContext::NONE),
124            reaches_into_outer_context: 0,
125            config_type: ATNConfigType::BaseATNConfig,
126        }
127    }
128
129    pub fn new_with_semantic(
130        state: ATNStateRef,
131        alt: isize,
132        context: Option<Arc<PredictionContext>>,
133        semantic_context: Box<SemanticContext>,
134    ) -> ATNConfig {
135        let mut new = Self::new(state, alt, context);
136        new.semantic_context = semantic_context;
137        new
138    }
139
140    pub fn new_lexer_atnconfig6(
141        _state: ATNStateRef,
142        _alt: isize,
143        _context: Arc<PredictionContext>,
144    ) -> ATNConfig {
145        let mut atnconfig = ATNConfig::new(_state, _alt, Some(_context));
146        atnconfig.config_type = ATNConfigType::LexerATNConfig {
147            lexer_action_executor: None,
148            passed_through_non_greedy_decision: false,
149        };
150        atnconfig
151    }
152
153    pub fn cloned_with_new_semantic(
154        &self,
155        target: &dyn ATNState,
156        ctx: Box<SemanticContext>,
157    ) -> ATNConfig {
158        let mut new = self.cloned(target);
159        new.semantic_context = ctx;
160        new
161    }
162
163    pub fn cloned(&self, target: &dyn ATNState) -> ATNConfig {
164        //        println!("depth {}",PredictionContext::size(self.context.as_deref()));
165        let mut new = self.clone();
166        new.state = target.get_state_number();
167        if let ATNConfigType::LexerATNConfig {
168            passed_through_non_greedy_decision,
169            ..
170        } = &mut new.config_type
171        {
172            *passed_through_non_greedy_decision = check_non_greedy_decision(self, target);
173        }
174        new
175    }
176
177    pub fn cloned_with_new_ctx(
178        &self,
179        target: &dyn ATNState,
180        ctx: Option<Arc<PredictionContext>>,
181    ) -> ATNConfig {
182        let mut new = self.cloned(target);
183        new.context = ctx;
184
185        new
186    }
187
188    pub(crate) fn cloned_with_new_exec(
189        &self,
190        target: &dyn ATNState,
191        exec: Option<LexerActionExecutor>,
192    ) -> ATNConfig {
193        let mut new = self.cloned(target);
194        if let ATNConfigType::LexerATNConfig {
195            lexer_action_executor,
196            passed_through_non_greedy_decision: _,
197        } = &mut new.config_type
198        {
199            *lexer_action_executor = exec.map(Box::new);
200            //            *passed_through_non_greedy_decision = check_non_greedy_decision(self, target);
201        }
202        new
203    }
204
205    pub fn get_state(&self) -> ATNStateRef { self.state }
206
207    pub fn get_alt(&self) -> isize { self.alt }
208
209    pub(crate) fn get_type(&self) -> &ATNConfigType { &self.config_type }
210
211    pub fn get_context(&self) -> Option<&Arc<PredictionContext>> { self.context.as_ref() }
212
213    pub fn take_context(&mut self) -> Arc<PredictionContext> { self.context.take().unwrap() }
214
215    pub fn set_context(&mut self, _v: Arc<PredictionContext>) { self.context = Some(_v); }
216
217    pub fn get_reaches_into_outer_context(&self) -> isize { self.reaches_into_outer_context }
218
219    pub fn set_reaches_into_outer_context(&mut self, _v: isize) {
220        self.reaches_into_outer_context = _v
221    }
222
223    pub fn is_precedence_filter_suppressed(&self) -> bool { self.precedence_filter_suppressed }
224
225    pub fn set_precedence_filter_suppressed(&mut self, _v: bool) {
226        self.precedence_filter_suppressed = _v;
227    }
228}
229
230fn check_non_greedy_decision(source: &ATNConfig, target: &dyn ATNState) -> bool {
231    if let LexerATNConfig {
232        passed_through_non_greedy_decision: true,
233        ..
234    } = source.get_type()
235    {
236        return true;
237    }
238    if let ATNStateType::DecisionState {
239        nongreedy: true, ..
240    } = target.get_state_type()
241    {
242        return true;
243    }
244    false
245}