1 //! The "Lane Table". In the paper, this is depicted like so: 2 //! 3 //! ``` 4 //! +-------+----+-----+----+------------+ 5 //! + State | C1 | ... | Cn | Successors | 6 //! +-------+----+-----+----+------------+ 7 //! ``` 8 //! 9 //! where each row summarizes some state that potentially contributes 10 //! lookahead to the conflict. The columns `Ci` represent each of the 11 //! conflicts we are trying to disentangle; their values are each 12 //! `TokenSet` indicating the lookahead contributing by this state. 13 //! The Successors is a vector of further successors. For simplicity 14 //! though we store this using maps, at least for now. 15 16 use collections::{Map, Multimap, Set}; 17 use grammar::repr::*; 18 use lr1::core::*; 19 use lr1::lookahead::*; 20 use std::default::Default; 21 use std::fmt::{Debug, Error, Formatter}; 22 use std::iter; 23 24 pub mod context_set; 25 use self::context_set::{ContextSet, OverlappingLookahead}; 26 27 #[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] 28 pub struct ConflictIndex { 29 index: usize, 30 } 31 32 impl ConflictIndex { new(index: usize) -> ConflictIndex33 pub fn new(index: usize) -> ConflictIndex { 34 ConflictIndex { index: index } 35 } 36 } 37 38 pub struct LaneTable<'grammar> { 39 _grammar: &'grammar Grammar, 40 conflicts: usize, 41 lookaheads: Map<(StateIndex, ConflictIndex), TokenSet>, 42 successors: Multimap<StateIndex, Set<StateIndex>>, 43 } 44 45 impl<'grammar> LaneTable<'grammar> { new(grammar: &'grammar Grammar, conflicts: usize) -> LaneTable46 pub fn new(grammar: &'grammar Grammar, conflicts: usize) -> LaneTable { 47 LaneTable { 48 _grammar: grammar, 49 conflicts: conflicts, 50 lookaheads: Map::default(), 51 successors: Multimap::default(), 52 } 53 } 54 add_lookahead(&mut self, state: StateIndex, conflict: ConflictIndex, tokens: &TokenSet)55 pub fn add_lookahead(&mut self, state: StateIndex, conflict: ConflictIndex, tokens: &TokenSet) { 56 self.lookaheads 57 .entry((state, conflict)) 58 .or_insert_with(|| TokenSet::new()) 59 .union_with(&tokens); 60 } 61 add_successor(&mut self, state: StateIndex, succ: StateIndex)62 pub fn add_successor(&mut self, state: StateIndex, succ: StateIndex) { 63 self.successors.push(state, succ); 64 } 65 66 /// Unions together the lookaheads for each column and returns a 67 /// context set containing all of them. For an LALR(1) grammar, 68 /// these token sets will be mutually disjoint, as discussed in 69 /// the [README]; otherwise `Err` will be returned. 70 /// 71 /// [README]: ../README.md columns(&self) -> Result<ContextSet, OverlappingLookahead>72 pub fn columns(&self) -> Result<ContextSet, OverlappingLookahead> { 73 let mut columns = ContextSet::new(self.conflicts); 74 for (&(_, conflict_index), set) in &self.lookaheads { 75 columns.insert(conflict_index, set)?; 76 } 77 Ok(columns) 78 } 79 successors(&self, state: StateIndex) -> Option<&Set<StateIndex>>80 pub fn successors(&self, state: StateIndex) -> Option<&Set<StateIndex>> { 81 self.successors.get(&state) 82 } 83 84 /// Returns the state of states in the table that are **not** 85 /// reachable from another state in the table. These are called 86 /// "beachhead states". beachhead_states(&self) -> Set<StateIndex>87 pub fn beachhead_states(&self) -> Set<StateIndex> { 88 // set of all states that are reachable from another state 89 let reachable: Set<StateIndex> = self 90 .successors 91 .iter() 92 .flat_map(|(_pred, succ)| succ) 93 .cloned() 94 .collect(); 95 96 self.lookaheads 97 .keys() 98 .map(|&(state_index, _)| state_index) 99 .filter(|s| !reachable.contains(s)) 100 .collect() 101 } 102 context_set(&self, state: StateIndex) -> Result<ContextSet, OverlappingLookahead>103 pub fn context_set(&self, state: StateIndex) -> Result<ContextSet, OverlappingLookahead> { 104 let mut set = ContextSet::new(self.conflicts); 105 for (&(state_index, conflict_index), token_set) in &self.lookaheads { 106 if state_index == state { 107 set.insert(conflict_index, token_set)?; 108 } 109 } 110 Ok(set) 111 } 112 113 /// Returns a map containing all states that appear in the table, 114 /// along with the context set for each state (i.e., each row in 115 /// the table, basically). Returns Err if any state has a conflict 116 /// between the context sets even within its own row. rows(&self) -> Result<Map<StateIndex, ContextSet>, StateIndex>117 pub fn rows(&self) -> Result<Map<StateIndex, ContextSet>, StateIndex> { 118 let mut map = Map::new(); 119 for (&(state_index, conflict_index), token_set) in &self.lookaheads { 120 debug!( 121 "rows: inserting state_index={:?} conflict_index={:?} token_set={:?}", 122 state_index, conflict_index, token_set 123 ); 124 match { 125 map.entry(state_index) 126 .or_insert_with(|| ContextSet::new(self.conflicts)) 127 .insert(conflict_index, token_set) 128 } { 129 Ok(_changed) => {} 130 Err(OverlappingLookahead) => { 131 debug!("rows: intra-row conflict inserting state_index={:?} conflict_index={:?} token_set={:?}", 132 state_index, conflict_index, token_set); 133 return Err(state_index); 134 } 135 } 136 } 137 138 // In some cases, there are states that have no context at 139 // all, only successors. In that case, make sure to add an 140 // empty row for them. 141 for (&state_index, _) in &self.successors { 142 map.entry(state_index) 143 .or_insert_with(|| ContextSet::new(self.conflicts)); 144 } 145 146 Ok(map) 147 } 148 } 149 150 impl<'grammar> Debug for LaneTable<'grammar> { fmt(&self, fmt: &mut Formatter) -> Result<(), Error>151 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> { 152 let indices: Set<StateIndex> = self 153 .lookaheads 154 .keys() 155 .map(|&(state, _)| state) 156 .chain(self.successors.iter().map(|(key, _)| key.clone())) 157 .collect(); 158 159 let header = iter::once(format!("State")) 160 .chain((0..self.conflicts).map(|i| format!("C{}", i))) 161 .chain(Some(format!("Successors"))) 162 .collect(); 163 164 let rows = indices.iter().map(|&index| { 165 iter::once(format!("{:?}", index)) 166 .chain((0..self.conflicts).map(|i| { 167 self.lookaheads 168 .get(&(index, ConflictIndex::new(i))) 169 .map(|token_set| format!("{:?}", token_set)) 170 .unwrap_or(String::new()) 171 })) 172 .chain(Some( 173 self.successors 174 .get(&index) 175 .map(|c| format!("{:?}", c)) 176 .unwrap_or(String::new()), 177 )) 178 .collect() 179 }); 180 181 let table: Vec<Vec<_>> = iter::once(header).chain(rows).collect(); 182 183 let columns = 2 + self.conflicts; 184 185 let widths: Vec<_> = (0..columns) 186 .map(|c| { 187 // find the max width of any row at this column 188 table.iter().map(|r| r[c].len()).max().unwrap() 189 }) 190 .collect(); 191 192 for row in &table { 193 try!(write!(fmt, "| ")); 194 for (i, column) in row.iter().enumerate() { 195 if i > 0 { 196 try!(write!(fmt, " | ")); 197 } 198 try!(write!(fmt, "{0:1$}", column, widths[i])); 199 } 200 try!(write!(fmt, " |\n")); 201 } 202 203 Ok(()) 204 } 205 } 206