From baf7f3603c5eca1c338be4665d516ff6d189a020 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 4 Jan 2019 11:30:53 -0800 Subject: [PATCH] Mark fragile tokens --- src/build_tables/mod.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/build_tables/mod.rs b/src/build_tables/mod.rs index 78798732..ed47665e 100644 --- a/src/build_tables/mod.rs +++ b/src/build_tables/mod.rs @@ -43,6 +43,11 @@ pub(crate) fn build_tables( &coincident_token_index, &token_conflict_map, ); + mark_fragile_tokens( + &mut parse_table, + lexical_grammar, + &token_conflict_map, + ); if minimize { minimize_parse_table( &mut parse_table, @@ -238,6 +243,34 @@ fn identify_keywords( keywords } +fn mark_fragile_tokens( + parse_table: &mut ParseTable, + lexical_grammar: &LexicalGrammar, + token_conflict_map: &TokenConflictMap, +) { + let n = lexical_grammar.variables.len(); + let mut valid_tokens_mask = Vec::with_capacity(n); + for state in parse_table.states.iter_mut() { + valid_tokens_mask.clear(); + valid_tokens_mask.resize(n, false); + for token in state.terminal_entries.keys() { + if token.is_terminal() { + valid_tokens_mask[token.index] = true; + } + } + for (token, entry) in state.terminal_entries.iter_mut() { + for i in 0..n { + if token_conflict_map.does_overlap(i, token.index) { + if valid_tokens_mask[i] { + entry.reusable = false; + break; + } + } + } + } + } +} + fn all_chars_are_alphabetical(cursor: &NfaCursor) -> bool { cursor.transition_chars().all(|(chars, is_sep)| { if is_sep {