diff --git a/spec/compiler/build_tables/parse_conflict_manager_spec.cc b/spec/compiler/build_tables/parse_conflict_manager_spec.cc index cbe2d5ca..4371d3e5 100644 --- a/spec/compiler/build_tables/parse_conflict_manager_spec.cc +++ b/spec/compiler/build_tables/parse_conflict_manager_spec.cc @@ -156,7 +156,7 @@ describe("ParseConflictManager", []() { describe("reduce/reduce conflicts", [&]() { describe("when one action has higher precedence", [&]() { ParseAction left = ParseAction::Reduce(sym2, 1, 0, AssociativityLeft, 0); - ParseAction right = ParseAction::Reduce(sym2, 1, 3, AssociativityLeft, 0); + ParseAction right = ParseAction::Reduce(sym2, 1, 2, AssociativityLeft, 0); it("favors that action", [&]() { result = conflict_manager->resolve(left, right, sym1); diff --git a/spec/compiler/prepare_grammar/flatten_grammar_spec.cc b/spec/compiler/prepare_grammar/flatten_grammar_spec.cc index 822de9cb..44f37b3a 100644 --- a/spec/compiler/prepare_grammar/flatten_grammar_spec.cc +++ b/spec/compiler/prepare_grammar/flatten_grammar_spec.cc @@ -138,14 +138,14 @@ describe("flatten_grammar", []() { AssertThat( get_precedence_sequences(grammar.variables[1].productions), Equals(vector>({ - { 0, 0, 101, 102, 101, 0 }, - { 0, 0, 101, 101, 0 } + { 0, 101, 102, 101, 0, 0 }, + { 0, 101, 101, 0, 0 } }))); AssertThat( get_precedence_sequences(grammar.variables[2].productions), Equals(vector>({ - { 0, 102, 0, 103 }, + { 102, 0, 103, 103 }, }))); }); @@ -155,8 +155,8 @@ describe("flatten_grammar", []() { AssertThat( get_associativity_sequences(grammar.variables[1].productions), Equals(vector>({ - { none, none, AssociativityLeft, AssociativityRight, AssociativityLeft, none }, - { none, none, AssociativityLeft, AssociativityLeft, none } + { none, AssociativityLeft, AssociativityRight, AssociativityLeft, none, none }, + { none, AssociativityLeft, AssociativityLeft, none, none } }))); }); diff --git a/src/compiler/build_tables/build_lex_table.cc b/src/compiler/build_tables/build_lex_table.cc index 07362ee1..5548173e 100644 --- a/src/compiler/build_tables/build_lex_table.cc +++ b/src/compiler/build_tables/build_lex_table.cc @@ -20,7 +20,6 @@ namespace tree_sitter { namespace build_tables { -using std::dynamic_pointer_cast; using std::make_shared; using std::map; using std::set; diff --git a/src/compiler/build_tables/build_parse_table.cc b/src/compiler/build_tables/build_parse_table.cc index ea106fba..266a9e5e 100644 --- a/src/compiler/build_tables/build_parse_table.cc +++ b/src/compiler/build_tables/build_parse_table.cc @@ -34,7 +34,7 @@ class ParseTableBuilder { const SyntaxGrammar grammar; const LexicalGrammar lexical_grammar; ParseConflictManager conflict_manager; - unordered_map parse_state_ids; + unordered_map parse_state_ids; vector> item_sets_to_process; ParseTable parse_table; std::set conflicts; @@ -112,18 +112,13 @@ class ParseTableBuilder { }; CompletionStatus get_completion_status(const ParseItem &item) { - CompletionStatus result{ false, 0, AssociativityNone }; const Production &production = grammar.productions(item.lhs())[item.production_index]; if (item.step_index == production.size()) { - result.is_done = true; - if (item.step_index > 0) { - const ProductionStep &step = production[item.step_index - 1]; - result.precedence = step.precedence; - result.associativity = step.associativity; - } + const ProductionStep &last_step = production[item.step_index - 1]; + return { true, last_step.precedence, last_step.associativity }; } - return result; + return { false, 0, AssociativityNone }; } void add_reduce_actions(const ParseItemSet &item_set, ParseStateId state_id) { @@ -239,12 +234,8 @@ class ParseTableBuilder { const ParseItem &item = pair.first; const Production &production = grammar.productions(item.lhs())[item.production_index]; - if (item.step_index > 0) { - if (item.step_index < production.size()) - result.add(production[item.step_index].precedence); - else - result.add(production[item.step_index - 1].precedence); - } + if (item.step_index > 0) + result.add(production[item.step_index - 1].precedence); } return result; } diff --git a/src/compiler/prepare_grammar/flatten_grammar.cc b/src/compiler/prepare_grammar/flatten_grammar.cc index 08f820f6..a58ea204 100644 --- a/src/compiler/prepare_grammar/flatten_grammar.cc +++ b/src/compiler/prepare_grammar/flatten_grammar.cc @@ -17,56 +17,36 @@ using std::string; using std::vector; class FlattenRule : public rules::RuleFn { - public: - bool has_pending_precedence; - int pending_precedence; + private: vector precedence_stack; - bool has_pending_associativity; - Associativity pending_associativity; vector associativity_stack; Production production; - FlattenRule() - : has_pending_precedence(false), - pending_precedence(0), - has_pending_associativity(false), - pending_associativity(AssociativityNone) {} - void apply_to(const rules::Symbol *sym) { - production.push_back( - ProductionStep(*sym, current_precedence(), current_associativity())); - - if (has_pending_precedence) { - precedence_stack.push_back(pending_precedence); - has_pending_precedence = false; - } - if (has_pending_associativity) { - associativity_stack.push_back(pending_associativity); - has_pending_associativity = false; - } + production.push_back(ProductionStep(*sym, precedence_stack.back(), + associativity_stack.back())); } void apply_to(const rules::Metadata *metadata) { int precedence = metadata->value_for(rules::PRECEDENCE); int associativity = metadata->value_for(rules::ASSOCIATIVITY); - if (precedence != 0) { - pending_precedence = precedence; - has_pending_precedence = true; - } - - if (associativity != 0) { - pending_associativity = static_cast(associativity); - has_pending_associativity = true; - } + if (precedence != 0) + precedence_stack.push_back(precedence); + if (associativity != 0) + associativity_stack.push_back(static_cast(associativity)); apply(metadata->rule); - if (precedence != 0) + if (precedence != 0) { precedence_stack.pop_back(); + production.back().precedence = precedence_stack.back(); + } - if (associativity != 0) + if (associativity != 0) { associativity_stack.pop_back(); + production.back().associativity = associativity_stack.back(); + } } void apply_to(const rules::Seq *seq) { @@ -74,28 +54,21 @@ class FlattenRule : public rules::RuleFn { apply(seq->right); } - private: - int current_precedence() { - if (precedence_stack.empty()) - return 0; - else - return precedence_stack.back(); - } + public: + FlattenRule() + : precedence_stack({ 0 }), associativity_stack({ AssociativityNone }) {} - Associativity current_associativity() { - if (associativity_stack.empty()) - return AssociativityNone; - else - return associativity_stack.back(); + Production flatten(const rule_ptr &rule) { + apply(rule); + size_t size = production.size(); + if (size > 1) { + production[size - 1].precedence = production[size - 2].precedence; + production[size - 1].associativity = production[size - 2].associativity; + } + return production; } }; -Production flatten_rule(const rule_ptr &rule) { - FlattenRule flattener; - flattener.apply(rule); - return flattener.production; -} - struct ProductionSlice { vector::const_iterator start; vector::const_iterator end; @@ -137,7 +110,7 @@ SyntaxGrammar flatten_grammar(const InitialSyntaxGrammar &grammar) { for (const Variable &variable : grammar.variables) { vector productions; for (const rule_ptr &rule_component : extract_choices(variable.rule)) - productions.push_back(flatten_rule(rule_component)); + productions.push_back(FlattenRule().flatten(rule_component)); result.variables.push_back( SyntaxVariable(variable.name, variable.type, productions)); }