Move state splitting algorithm into its own file
This commit is contained in:
parent
f85ce2fbfa
commit
0a3f2131c8
5 changed files with 66 additions and 66 deletions
|
|
@ -1,7 +1,7 @@
|
|||
use super::coincident_tokens::CoincidentTokenIndex;
|
||||
use super::item::TokenSet;
|
||||
use super::split_state_id_groups;
|
||||
use super::token_conflicts::TokenConflictMap;
|
||||
use crate::generate::dedup::split_state_id_groups;
|
||||
use crate::generate::grammars::{LexicalGrammar, SyntaxGrammar};
|
||||
use crate::generate::nfa::{CharacterSet, NfaCursor};
|
||||
use crate::generate::rules::Symbol;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use super::item::TokenSet;
|
||||
use super::split_state_id_groups;
|
||||
use super::token_conflicts::TokenConflictMap;
|
||||
use crate::generate::dedup::split_state_id_groups;
|
||||
use crate::generate::grammars::{LexicalGrammar, SyntaxGrammar, VariableType};
|
||||
use crate::generate::rules::{AliasMap, Symbol};
|
||||
use crate::generate::tables::{ParseAction, ParseState, ParseStateId, ParseTable, ParseTableEntry};
|
||||
|
|
|
|||
|
|
@ -349,67 +349,3 @@ fn all_chars_are_alphabetical(cursor: &NfaCursor) -> bool {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn split_state_id_groups<S>(
|
||||
states: &Vec<S>,
|
||||
state_ids_by_group_id: &mut Vec<Vec<usize>>,
|
||||
group_ids_by_state_id: &mut Vec<usize>,
|
||||
start_group_id: usize,
|
||||
mut f: impl FnMut(&S, &S, &Vec<usize>) -> bool,
|
||||
) -> bool {
|
||||
let mut result = false;
|
||||
|
||||
let mut group_id = start_group_id;
|
||||
while group_id < state_ids_by_group_id.len() {
|
||||
let state_ids = &state_ids_by_group_id[group_id];
|
||||
let mut split_state_ids = Vec::new();
|
||||
|
||||
let mut i = 0;
|
||||
while i < state_ids.len() {
|
||||
let left_state_id = state_ids[i];
|
||||
if split_state_ids.contains(&left_state_id) {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
let left_state = &states[left_state_id];
|
||||
|
||||
// Identify all of the other states in the group that are incompatible with
|
||||
// this state.
|
||||
let mut j = i + 1;
|
||||
while j < state_ids.len() {
|
||||
let right_state_id = state_ids[j];
|
||||
if split_state_ids.contains(&right_state_id) {
|
||||
j += 1;
|
||||
continue;
|
||||
}
|
||||
let right_state = &states[right_state_id];
|
||||
|
||||
if f(left_state, right_state, &group_ids_by_state_id) {
|
||||
split_state_ids.push(right_state_id);
|
||||
}
|
||||
|
||||
j += 1;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// If any states were removed from the group, add them all as a new group.
|
||||
if split_state_ids.len() > 0 {
|
||||
result = true;
|
||||
state_ids_by_group_id[group_id].retain(|i| !split_state_ids.contains(&i));
|
||||
|
||||
let new_group_id = state_ids_by_group_id.len();
|
||||
for id in &split_state_ids {
|
||||
group_ids_by_state_id[*id] = new_group_id;
|
||||
}
|
||||
|
||||
state_ids_by_group_id.push(split_state_ids);
|
||||
}
|
||||
|
||||
group_id += 1;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
|
|
|||
63
cli/src/generate/dedup.rs
Normal file
63
cli/src/generate/dedup.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
pub(crate) fn split_state_id_groups<S>(
|
||||
states: &Vec<S>,
|
||||
state_ids_by_group_id: &mut Vec<Vec<usize>>,
|
||||
group_ids_by_state_id: &mut Vec<usize>,
|
||||
start_group_id: usize,
|
||||
mut f: impl FnMut(&S, &S, &Vec<usize>) -> bool,
|
||||
) -> bool {
|
||||
let mut result = false;
|
||||
|
||||
let mut group_id = start_group_id;
|
||||
while group_id < state_ids_by_group_id.len() {
|
||||
let state_ids = &state_ids_by_group_id[group_id];
|
||||
let mut split_state_ids = Vec::new();
|
||||
|
||||
let mut i = 0;
|
||||
while i < state_ids.len() {
|
||||
let left_state_id = state_ids[i];
|
||||
if split_state_ids.contains(&left_state_id) {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
let left_state = &states[left_state_id];
|
||||
|
||||
// Identify all of the other states in the group that are incompatible with
|
||||
// this state.
|
||||
let mut j = i + 1;
|
||||
while j < state_ids.len() {
|
||||
let right_state_id = state_ids[j];
|
||||
if split_state_ids.contains(&right_state_id) {
|
||||
j += 1;
|
||||
continue;
|
||||
}
|
||||
let right_state = &states[right_state_id];
|
||||
|
||||
if f(left_state, right_state, &group_ids_by_state_id) {
|
||||
split_state_ids.push(right_state_id);
|
||||
}
|
||||
|
||||
j += 1;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// If any states were removed from the group, add them all as a new group.
|
||||
if split_state_ids.len() > 0 {
|
||||
result = true;
|
||||
state_ids_by_group_id[group_id].retain(|i| !split_state_ids.contains(&i));
|
||||
|
||||
let new_group_id = state_ids_by_group_id.len();
|
||||
for id in &split_state_ids {
|
||||
group_ids_by_state_id[*id] = new_group_id;
|
||||
}
|
||||
|
||||
state_ids_by_group_id.push(split_state_ids);
|
||||
}
|
||||
|
||||
group_id += 1;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ use std::path::{Path, PathBuf};
|
|||
use std::process::{Command, Stdio};
|
||||
|
||||
mod build_tables;
|
||||
mod dedup;
|
||||
mod grammars;
|
||||
mod nfa;
|
||||
mod node_types;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue