Handle ambiguities between extra and non-extra tokens using normal GLR splitting

This commit is contained in:
Max Brunsfeld 2016-09-06 10:22:16 -07:00
parent d31934ac77
commit b76574e01c
8 changed files with 63 additions and 100 deletions

View file

@ -81,9 +81,6 @@ class ParseTableBuilder {
process_part_state_queue();
allow_any_conflict = false;
for (ParseStateId state = 0; state < parse_table.states.size(); state++)
add_reduce_extra_actions(state);
mark_fragile_actions();
remove_duplicate_parse_states();
@ -198,31 +195,10 @@ class ParseTableBuilder {
ParseAction action = ParseAction::ShiftExtra();
ParseState &state = parse_table.states[state_id];
for (const Symbol &extra_symbol : grammar.extra_tokens)
if (!state.entries.count(extra_symbol) ||
(allow_any_conflict &&
state.entries[extra_symbol].actions.back().type ==
ParseActionTypeReduce))
if (!state.entries.count(extra_symbol) || state.has_shift_action() || allow_any_conflict)
parse_table.add_action(state_id, extra_symbol, action);
}
void add_reduce_extra_actions(ParseStateId state_id) {
const ParseState &state = parse_table.states[state_id];
for (const Symbol &extra_symbol : grammar.extra_tokens) {
const auto &entry_for_symbol = state.entries.find(extra_symbol);
if (entry_for_symbol == state.entries.end())
continue;
for (const ParseAction &action : entry_for_symbol->second.actions)
if (action.type == ParseActionTypeShift && !action.extra) {
size_t dest_state_id = action.state_index;
ParseAction reduce_extra = ParseAction::ReduceExtra(extra_symbol);
for (const auto &pair : state.entries)
add_action(dest_state_id, pair.first, reduce_extra, null_item_set);
}
}
}
void mark_fragile_actions() {
for (ParseState &state : parse_table.states) {
set<Symbol> symbols_with_multiple_actions;

View file

@ -340,9 +340,7 @@ class CCodeGenerator {
}
break;
case ParseActionTypeReduce:
if (action.extra) {
add("REDUCE_EXTRA(" + symbol_id(action.symbol) + ")");
} else if (action.fragile) {
if (action.fragile) {
add("REDUCE_FRAGILE(" + symbol_id(action.symbol) + ", " +
to_string(action.consumed_symbol_count) + ")");
} else {

View file

@ -65,15 +65,6 @@ ParseAction ParseAction::ShiftExtra() {
return action;
}
ParseAction ParseAction::ReduceExtra(Symbol symbol) {
ParseAction action;
action.type = ParseActionTypeReduce;
action.extra = true;
action.symbol = symbol;
action.consumed_symbol_count = 1;
return action;
}
ParseAction ParseAction::Reduce(Symbol symbol, size_t consumed_symbol_count,
int precedence,
rules::Associativity associativity,
@ -133,6 +124,13 @@ bool ParseTableEntry::operator==(const ParseTableEntry &other) const {
ParseState::ParseState() : lex_state_id(-1) {}
bool ParseState::has_shift_action() const {
for (const auto &pair : entries)
if (pair.second.actions.size() > 0 && pair.second.actions.back().type == ParseActionTypeShift)
return true;
return false;
}
set<Symbol> ParseState::expected_inputs() const {
set<Symbol> result;
for (auto &entry : entries)

View file

@ -38,7 +38,6 @@ class ParseAction {
int precedence, rules::Associativity,
const Production &);
static ParseAction ShiftExtra();
static ParseAction ReduceExtra(rules::Symbol symbol);
bool operator==(const ParseAction &) const;
bool operator<(const ParseAction &) const;
@ -74,6 +73,7 @@ class ParseState {
bool operator==(const ParseState &) const;
bool merge(const ParseState &);
void each_advance_action(std::function<void(ParseAction *)>);
bool has_shift_action() const;
std::map<rules::Symbol, ParseTableEntry> entries;
LexStateId lex_state_id;