use std::slice::Iter;
use crate::atn::ATN;
use crate::atn_deserialization_options::ATNDeserializationOptions;
use crate::atn_state::ATNState;
use crate::atn_state::BaseATNState;
use crate::atn_state::*;
use crate::atn_type::ATNType;
use crate::int_stream::EOF;
use crate::interval_set::IntervalSet;
use crate::interval_set::IntervalSetBuf;
use crate::lexer_action::*;
use crate::transition::Transition;
use crate::transition::*;
const SERIALIZED_VERSION: i32 = 4;
#[derive(Debug)]
pub struct ATNDeserializer {
deserialization_options: ATNDeserializationOptions,
}
impl ATNDeserializer {
pub fn new(options: Option<ATNDeserializationOptions>) -> ATNDeserializer {
ATNDeserializer {
deserialization_options: options.unwrap_or_default(),
}
}
pub fn deserialize(&self, data: &mut Iter<i32>) -> ATN {
self.check_version(*data.next().unwrap());
let mut atn = self.read_atn(data);
self.read_states(&mut atn, data);
self.read_rules(&mut atn, data);
self.read_modes(&mut atn, data);
let sets = self
.read_sets(&mut atn, data)
.into_iter()
.map(|x| x.into_static() as &'static _)
.collect::<Vec<_>>();
self.read_edges(&mut atn, data, &sets);
self.read_decisions(&mut atn, data);
if atn.grammar_type == ATNType::Lexer {
self.read_lexer_actions(&mut atn, data);
}
self.mark_precedence_decisions(&mut atn, data);
if self.deserialization_options.is_verify() {
self.verify_atn(&mut atn, data);
}
atn
}
fn check_version(&self, version: i32) {
if version != self::SERIALIZED_VERSION {
panic!(
"Could not deserialize ATN with version {} (expected {})",
version, SERIALIZED_VERSION
);
}
}
fn read_atn(&self, data: &mut Iter<i32>) -> ATN {
ATN::new_atn(
match data.next() {
Some(0) => ATNType::Lexer,
Some(1) => ATNType::Parser,
_ => panic!("invalid ATN type"),
},
*data.next().unwrap(),
)
}
fn read_states(&self, atn: &mut ATN, data: &mut Iter<i32>) {
let states_count = *data.next().unwrap();
atn.alloc_states(states_count as usize);
for i in 0..states_count {
let state_type = *data.next().unwrap();
if state_type == ATNSTATE_INVALID_STATE_NUMBER {
atn.add_state(self.state_factory(ATNSTATE_INVALID_TYPE, -1, i));
panic!("why invalid state serialized?");
}
let mut rule_index = *data.next().unwrap();
if rule_index == 0xFFFF {
rule_index = -1;
}
let mut state = self.state_factory(state_type, rule_index, i);
match state.state_type() {
ATNStateType::BasicBlockStart
| ATNStateType::StarBlockStart
| ATNStateType::PlusBlockStart => {
let end_state = state.get_decision_end_state_mut().unwrap();
*end_state = atn.make_state_ref(*data.next().unwrap());
}
ATNStateType::LoopEnd => {
let LoopEndState {
ref mut loop_back_state,
..
} = state.try_as_mut().unwrap();
*loop_back_state = atn.make_state_ref(*data.next().unwrap());
}
_ => (),
}
atn.add_state(state);
}
let num_non_greedy = *data.next().unwrap();
for _ in 0..num_non_greedy {
let st = *data.next().unwrap();
if let Some(nongreedy) = atn.get_state_mut(st).get_nongreedy_decision_mut() {
*nongreedy = true
}
}
if true {
let num_precedence_states = *data.next().unwrap();
for _ in 0..num_precedence_states {
let st = *data.next().unwrap();
if let Some(RuleStartState {
ref mut is_left_recursive,
..
}) = atn.get_state_mut(st).try_as_mut()
{
*is_left_recursive = true
}
}
}
}
fn read_rules(&self, atn: &mut ATN, data: &mut Iter<i32>) {
let nrules = *data.next().unwrap() as usize;
atn.rule_to_start_state
.resize(nrules, ATNStateRef::invalid());
for i in 0..nrules {
atn.rule_to_start_state[i] = atn.make_state_ref(*data.next().unwrap());
if atn.grammar_type == ATNType::Lexer {
let token_type = *data.next().unwrap();
atn.rule_to_token_type.push(token_type);
}
}
atn.rule_to_stop_state
.resize(nrules, ATNStateRef::invalid());
for i in 0..atn.states_count() {
let state = atn.get_state(i as i32);
if state.state_type() == ATNStateType::RuleStop {
let rule_index = state.get_rule_index() as usize;
atn.rule_to_stop_state[rule_index] = atn.make_state_ref(i as i32);
unsafe {
if let Some(RuleStartState {
ref mut stop_state, ..
}) = atn.rule_to_start_state[rule_index].as_mut().try_as_mut()
{
*stop_state = atn.make_state_ref(i as i32)
}
}
}
}
}
fn read_modes(&self, atn: &mut ATN, data: &mut Iter<i32>) {
let nmodes = *data.next().unwrap();
for _i in 0..nmodes {
atn.mode_to_start_state
.push(atn.make_state_ref(*data.next().unwrap()));
}
}
fn read_sets(&self, _atn: &mut ATN, data: &mut Iter<i32>) -> Vec<IntervalSetBuf> {
let nsets = *data.next().unwrap();
let mut sets = Vec::new();
for _i in 0..nsets {
let intervals = *data.next().unwrap();
let mut set = IntervalSetBuf::new();
if *data.next().unwrap() != 0 {
set.add_one(-1)
}
for _ in 0..intervals {
set.add_range(*data.next().unwrap(), *data.next().unwrap());
}
sets.push(set);
}
sets
}
fn read_edges(&self, atn: &mut ATN, data: &mut Iter<i32>, sets: &[&'static IntervalSet]) {
let nedges = *data.next().unwrap();
for _i in 0..nedges {
let src = *data.next().unwrap();
let trg = *data.next().unwrap();
let ttype = *data.next().unwrap();
let arg1 = *data.next().unwrap();
let arg2 = *data.next().unwrap();
let arg3 = *data.next().unwrap();
let transition = self.edge_factory(
atn,
ttype,
atn.make_state_ref(src),
atn.make_state_ref(trg),
arg1,
arg2,
arg3,
sets,
);
atn.get_state_mut(src).add_transition(transition);
}
for i in atn.iter_states() {
for tr in i.get_transitions() {
match tr.try_as::<RuleTransition>() {
Some(tr) => {
let target = tr.get_target();
let outermost_prec_return = if let Some(RuleStartState {
is_left_recursive: true,
..
}) =
atn.rule_to_start_state[target.get_rule_index() as usize].try_as()
{
if tr.precedence() == 0 {
target.get_rule_index()
} else {
-1
}
} else {
-1
};
let return_tr =
EpsilonTransition::create(tr.follow_state, outermost_prec_return);
unsafe {
atn.rule_to_stop_state[target.get_rule_index() as usize]
.as_mut()
.add_transition(return_tr);
}
}
_ => continue,
}
}
}
}
fn read_decisions(&self, atn: &mut ATN, _data: &mut Iter<i32>) {
let ndecisions = *_data.next().unwrap();
for i in 0..ndecisions {
let s = atn.make_state_ref(*_data.next().unwrap());
atn.decision_to_state.push(s);
if let Some(decision) = unsafe { s.as_mut() }.get_decision_mut() {
*decision = i
}
}
}
fn read_lexer_actions(&self, atn: &mut ATN, _data: &mut Iter<i32>) {
let nactions = *_data.next().unwrap();
for _i in 0..nactions {
let action_type = *_data.next().unwrap();
let data1 = *_data.next().unwrap();
let data2 = *_data.next().unwrap();
let lexer_action = self.lexer_action_factory(action_type, data1, data2);
atn.lexer_actions.push(lexer_action);
}
}
fn mark_precedence_decisions(&self, _atn: &mut ATN, _data: &mut Iter<i32>) {
let mut precedence_states = Vec::new();
for state in _atn.iter_states() {
if let Some(StarLoopEntryState { .. }) = state.try_as() {
if let Some(RuleStartState {
is_left_recursive: true,
..
}) = _atn.rule_to_start_state[state.get_rule_index() as usize].try_as()
{
let maybe_loop_end =
state.get_transitions().iter().last().unwrap().get_target();
if maybe_loop_end.state_type() == ATNStateType::LoopEnd
&& maybe_loop_end.has_epsilon_only_transitions()
&& maybe_loop_end.get_transitions()[0]
.get_target()
.state_type()
== ATNStateType::RuleStop
{
precedence_states.push(state.get_state_number())
}
}
}
}
for st in precedence_states.into_iter() {
if let Some(StarLoopEntryState {
ref mut is_precedence,
..
}) = _atn.get_state_mut(st).try_as_mut()
{
*is_precedence = true
}
}
}
fn verify_atn(&self, _atn: &mut ATN, _data: &mut Iter<i32>) {
}
#[allow(clippy::too_many_arguments)]
fn edge_factory(
&self,
atn: &ATN,
type_index: i32,
_src: ATNStateRef,
target: ATNStateRef,
arg1: i32,
arg2: i32,
arg3: i32,
sets: &[&'static IntervalSet],
) -> Transition {
match type_index {
TRANSITION_EPSILON => EpsilonTransition::create(target, 0),
TRANSITION_RANGE => RangeTransition::create(
target,
if arg3 != 0 {
super::token::TOKEN_EOF
} else {
arg1
},
arg2,
),
TRANSITION_RULE => RuleTransition::create(atn.make_state_ref(arg1), target, arg2, arg3),
TRANSITION_PREDICATE => PredicateTransition::create(target, arg3 != 0, arg1, arg2),
TRANSITION_ATOM => AtomTransition::create(target, if arg3 != 0 { EOF } else { arg1 }),
TRANSITION_ACTION => ActionTransition::create(target, arg3 != 0, arg1, arg2, 0),
TRANSITION_SET => SetTransition::create(target, sets[arg1 as usize]),
TRANSITION_NOTSET => NotSetTransition::create(target, sets[arg1 as usize]),
TRANSITION_WILDCARD => WildcardTransition::create(target),
TRANSITION_PRECEDENCE => PrecedencePredicateTransition::create(target, arg1),
_ => panic!("invalid transition type"),
}
}
fn state_factory(&self, type_index: i32, rule_index: i32, state_number: i32) -> ATNState {
let base = BaseATNState::new(state_number, rule_index, type_index);
match type_index {
ATNSTATE_INVALID_TYPE => ATNState::default(),
ATNSTATE_BASIC => BasicState::create(base),
ATNSTATE_RULE_START => RuleStartState::create(base, ATNStateRef::invalid(), false),
ATNSTATE_BLOCK_START => {
BasicBlockStartState::create(base, -1, false, ATNStateRef::invalid())
}
ATNSTATE_PLUS_BLOCK_START => PlusBlockStartState::create(
base,
-1,
false,
ATNStateRef::invalid(),
ATNStateRef::invalid(),
),
ATNSTATE_STAR_BLOCK_START => {
StarBlockStartState::create(base, -1, false, ATNStateRef::invalid())
}
ATNSTATE_TOKEN_START => TokenStartState::create(base, -1, false),
ATNSTATE_RULE_STOP => RuleStopState::create(base),
ATNSTATE_BLOCK_END => BlockEndState::create(base, ATNStateRef::invalid()),
ATNSTATE_STAR_LOOP_BACK => StarLoopbackState::create(base),
ATNSTATE_STAR_LOOP_ENTRY => {
StarLoopEntryState::create(base, -1, false, ATNStateRef::invalid(), false)
}
ATNSTATE_PLUS_LOOP_BACK => PlusLoopBackState::create(base, -1, false),
ATNSTATE_LOOP_END => LoopEndState::create(base, ATNStateRef::invalid()),
t => panic!("invalid ATN state type {}", t),
}
}
fn lexer_action_factory(
&self,
action_type: i32,
data1: i32,
data2: i32,
) -> LexerAction<'static> {
match action_type {
LEXER_ACTION_TYPE_CHANNEL => LexerAction::Channel(data1),
LEXER_ACTION_TYPE_CUSTOM => LexerAction::Custom {
rule_index: data1,
action_index: data2,
},
LEXER_ACTION_TYPE_MODE => LexerAction::Mode(data1),
LEXER_ACTION_TYPE_MORE => LexerAction::More,
LEXER_ACTION_TYPE_POP_MODE => LexerAction::PopMode,
LEXER_ACTION_TYPE_PUSH_MODE => LexerAction::PushMode(data1),
LEXER_ACTION_TYPE_SKIP => LexerAction::Skip,
LEXER_ACTION_TYPE_TYPE => LexerAction::Type(data1),
_ => panic!("invalid action type {}", action_type),
}
}
}