Skip to content

Commit 29bc26e

Browse files
committed
Fix test failure after non-terminal extras change
1 parent 796f655 commit 29bc26e

File tree

7 files changed

+65
-24
lines changed

7 files changed

+65
-24
lines changed

cli/src/generate/build_tables/build_parse_table.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ impl<'a> ParseTableBuilder<'a> {
9090
production,
9191
step_index: 1,
9292
},
93-
&[Symbol::end()].iter().cloned().collect(),
93+
&[Symbol::end_of_nonterminal_extra()]
94+
.iter()
95+
.cloned()
96+
.collect(),
9497
);
9598
}
9699
}
@@ -304,7 +307,7 @@ impl<'a> ParseTableBuilder<'a> {
304307

305308
// Finally, add actions for the grammar's `extra` symbols.
306309
let state = &mut self.parse_table.states[state_id];
307-
let is_end_of_non_terminal_extra = state.is_end_of_non_terminal_extra(&self.syntax_grammar);
310+
let is_end_of_non_terminal_extra = state.is_end_of_non_terminal_extra();
308311

309312
// If this state represents the end of a non-terminal extra rule, then make sure that
310313
// it doesn't have other successor states. Non-terminal extra rules must have
@@ -315,7 +318,7 @@ impl<'a> ParseTableBuilder<'a> {
315318
.entries
316319
.iter()
317320
.filter_map(|(item, _)| {
318-
if item.step_index > 0 {
321+
if !item.is_augmented() && item.step_index > 0 {
319322
Some(item.variable_index)
320323
} else {
321324
None
@@ -817,7 +820,7 @@ impl<'a> ParseTableBuilder<'a> {
817820

818821
fn symbol_name(&self, symbol: &Symbol) -> String {
819822
match symbol.kind {
820-
SymbolType::End => "EOF".to_string(),
823+
SymbolType::End | SymbolType::EndOfNonTerminalExtra => "EOF".to_string(),
821824
SymbolType::External => self.syntax_grammar.external_tokens[symbol.index]
822825
.name
823826
.clone(),

cli/src/generate/build_tables/item_set_builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ impl<'a> fmt::Debug for ParseItemSetBuilder<'a> {
306306
SymbolType::NonTerminal => &self.syntax_grammar.variables[symbol.index].name,
307307
SymbolType::External => &self.syntax_grammar.external_tokens[symbol.index].name,
308308
SymbolType::Terminal => &self.lexical_grammar.variables[symbol.index].name,
309-
SymbolType::End => "END",
309+
SymbolType::End | SymbolType::EndOfNonTerminalExtra => "END",
310310
};
311311
write!(
312312
f,
@@ -323,7 +323,7 @@ impl<'a> fmt::Debug for ParseItemSetBuilder<'a> {
323323
SymbolType::NonTerminal => &self.syntax_grammar.variables[symbol.index].name,
324324
SymbolType::External => &self.syntax_grammar.external_tokens[symbol.index].name,
325325
SymbolType::Terminal => &self.lexical_grammar.variables[symbol.index].name,
326-
SymbolType::End => "END",
326+
SymbolType::End | SymbolType::EndOfNonTerminalExtra => "END",
327327
};
328328
write!(
329329
f,

cli/src/generate/build_tables/minimize_parse_table.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,14 @@ impl<'a> Minimizer<'a> {
366366
existing_tokens: impl Iterator<Item = &'b Symbol>,
367367
new_token: Symbol,
368368
) -> bool {
369+
if new_token == Symbol::end_of_nonterminal_extra() {
370+
info!(
371+
"split states {} {} - end of non-terminal extra",
372+
left_id, right_id,
373+
);
374+
return true;
375+
}
376+
369377
// Do not add external tokens; they could conflict lexically with any of the state's
370378
// existing lookahead tokens.
371379
if new_token.is_external() {

cli/src/generate/prepare_grammar/extract_default_aliases.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ pub(super) fn extract_default_aliases(
3535
SymbolType::External => &mut external_status_list[step.symbol.index],
3636
SymbolType::NonTerminal => &mut non_terminal_status_list[step.symbol.index],
3737
SymbolType::Terminal => &mut terminal_status_list[step.symbol.index],
38-
SymbolType::End => panic!("Unexpected end token"),
38+
SymbolType::End | SymbolType::EndOfNonTerminalExtra => {
39+
panic!("Unexpected end token")
40+
}
3941
};
4042

4143
// Default aliases don't work for inlined variables.
@@ -111,7 +113,9 @@ pub(super) fn extract_default_aliases(
111113
SymbolType::External => &mut external_status_list[step.symbol.index],
112114
SymbolType::NonTerminal => &mut non_terminal_status_list[step.symbol.index],
113115
SymbolType::Terminal => &mut terminal_status_list[step.symbol.index],
114-
SymbolType::End => panic!("Unexpected end token"),
116+
SymbolType::End | SymbolType::EndOfNonTerminalExtra => {
117+
panic!("Unexpected end token")
118+
}
115119
};
116120

117121
// If this step is aliased as the symbol's default alias, then remove that alias.

cli/src/generate/render.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ impl Generator {
142142
for i in 0..self.parse_table.symbols.len() {
143143
self.assign_symbol_id(self.parse_table.symbols[i], &mut symbol_identifiers);
144144
}
145+
self.symbol_ids.insert(
146+
Symbol::end_of_nonterminal_extra(),
147+
self.symbol_ids[&Symbol::end()].clone(),
148+
);
145149

146150
self.symbol_map = self
147151
.parse_table
@@ -970,7 +974,7 @@ impl Generator {
970974
add_line!(self, "static TSLexMode ts_lex_modes[STATE_COUNT] = {{");
971975
indent!(self);
972976
for (i, state) in self.parse_table.states.iter().enumerate() {
973-
if state.is_end_of_non_terminal_extra(&self.syntax_grammar) {
977+
if state.is_end_of_non_terminal_extra() {
974978
add_line!(self, "[{}] = {{(TSStateId)(-1)}},", i,);
975979
} else if state.external_lex_state_id > 0 {
976980
add_line!(
@@ -1479,7 +1483,7 @@ impl Generator {
14791483

14801484
fn metadata_for_symbol(&self, symbol: Symbol) -> (&str, VariableType) {
14811485
match symbol.kind {
1482-
SymbolType::End => ("end", VariableType::Hidden),
1486+
SymbolType::End | SymbolType::EndOfNonTerminalExtra => ("end", VariableType::Hidden),
14831487
SymbolType::NonTerminal => {
14841488
let variable = &self.syntax_grammar.variables[symbol.index];
14851489
(&variable.name, variable.kind)

cli/src/generate/rules.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::iter::FromIterator;
77
pub(crate) enum SymbolType {
88
External,
99
End,
10+
EndOfNonTerminalExtra,
1011
Terminal,
1112
NonTerminal,
1213
}
@@ -69,6 +70,7 @@ pub(crate) struct TokenSet {
6970
terminal_bits: SmallBitVec,
7071
external_bits: SmallBitVec,
7172
eof: bool,
73+
end_of_nonterminal_extra: bool,
7274
}
7375

7476
impl Rule {
@@ -221,6 +223,13 @@ impl Symbol {
221223
index: 0,
222224
}
223225
}
226+
227+
pub fn end_of_nonterminal_extra() -> Self {
228+
Symbol {
229+
kind: SymbolType::EndOfNonTerminalExtra,
230+
index: 0,
231+
}
232+
}
224233
}
225234

226235
impl From<Symbol> for Rule {
@@ -235,6 +244,7 @@ impl TokenSet {
235244
terminal_bits: SmallBitVec::new(),
236245
external_bits: SmallBitVec::new(),
237246
eof: false,
247+
end_of_nonterminal_extra: false,
238248
}
239249
}
240250

@@ -262,6 +272,11 @@ impl TokenSet {
262272
}),
263273
)
264274
.chain(if self.eof { Some(Symbol::end()) } else { None })
275+
.chain(if self.end_of_nonterminal_extra {
276+
Some(Symbol::end_of_nonterminal_extra())
277+
} else {
278+
None
279+
})
265280
}
266281

267282
pub fn terminals<'a>(&'a self) -> impl Iterator<Item = Symbol> + 'a {
@@ -283,6 +298,7 @@ impl TokenSet {
283298
SymbolType::Terminal => self.terminal_bits.get(symbol.index).unwrap_or(false),
284299
SymbolType::External => self.external_bits.get(symbol.index).unwrap_or(false),
285300
SymbolType::End => self.eof,
301+
SymbolType::EndOfNonTerminalExtra => self.end_of_nonterminal_extra,
286302
}
287303
}
288304

@@ -299,6 +315,10 @@ impl TokenSet {
299315
self.eof = true;
300316
return;
301317
}
318+
SymbolType::EndOfNonTerminalExtra => {
319+
self.end_of_nonterminal_extra = true;
320+
return;
321+
}
302322
};
303323
if other.index >= vec.len() {
304324
vec.resize(other.index + 1, false);
@@ -315,14 +335,21 @@ impl TokenSet {
315335
self.eof = false;
316336
return;
317337
}
338+
SymbolType::EndOfNonTerminalExtra => {
339+
self.end_of_nonterminal_extra = false;
340+
return;
341+
}
318342
};
319343
if other.index < vec.len() {
320344
vec.set(other.index, false);
321345
}
322346
}
323347

324348
pub fn is_empty(&self) -> bool {
325-
!self.eof && !self.terminal_bits.iter().any(|a| a) && !self.external_bits.iter().any(|a| a)
349+
!self.eof
350+
&& !self.end_of_nonterminal_extra
351+
&& !self.terminal_bits.iter().any(|a| a)
352+
&& !self.external_bits.iter().any(|a| a)
326353
}
327354

328355
pub fn insert_all_terminals(&mut self, other: &TokenSet) -> bool {
@@ -359,6 +386,10 @@ impl TokenSet {
359386
result |= !self.eof;
360387
self.eof = true;
361388
}
389+
if other.end_of_nonterminal_extra {
390+
result |= !self.end_of_nonterminal_extra;
391+
self.end_of_nonterminal_extra = true;
392+
}
362393
result |= self.insert_all_terminals(other);
363394
result |= self.insert_all_externals(other);
364395
result

cli/src/generate/tables.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
use super::nfa::CharacterSet;
12
use super::rules::{Alias, Associativity, Symbol, TokenSet};
2-
use super::{grammars::SyntaxGrammar, nfa::CharacterSet};
33
use std::collections::{BTreeMap, HashMap};
44
pub(crate) type ProductionInfoId = usize;
55
pub(crate) type ParseStateId = usize;
@@ -101,18 +101,9 @@ impl Default for LexTable {
101101
}
102102

103103
impl ParseState {
104-
pub fn is_end_of_non_terminal_extra(&self, grammar: &SyntaxGrammar) -> bool {
105-
if let Some(eof_entry) = self.terminal_entries.get(&Symbol::end()) {
106-
eof_entry.actions.iter().any(|action| {
107-
if let ParseAction::Reduce { symbol, .. } = action {
108-
grammar.extra_symbols.contains(&symbol)
109-
} else {
110-
false
111-
}
112-
})
113-
} else {
114-
false
115-
}
104+
pub fn is_end_of_non_terminal_extra(&self) -> bool {
105+
self.terminal_entries
106+
.contains_key(&Symbol::end_of_nonterminal_extra())
116107
}
117108

118109
pub fn referenced_states<'a>(&'a self) -> impl Iterator<Item = ParseStateId> + 'a {

0 commit comments

Comments
 (0)