🎨 flatten_grammar

This commit is contained in:
Max Brunsfeld 2016-11-09 20:25:20 -08:00
parent 89c01a7b22
commit 7bcae8f6a8
2 changed files with 29 additions and 33 deletions

View file

@ -6,9 +6,8 @@
#include "helpers/rule_helpers.h"
template<typename T, typename Func>
std::vector<typename std::result_of<Func(T)>::type>
collect(const std::vector<T> &v, Func f) {
vector<typename std::result_of<Func(T)>::type> result;
vector<typename result_of<Func(T)>::type> collect(const vector<T> &v, Func f) {
vector<typename result_of<Func(T)>::type> result;
for (const T &item : v)
result.push_back(f(item));
return result;
@ -21,6 +20,30 @@ using prepare_grammar::flatten_grammar;
using prepare_grammar::InitialSyntaxGrammar;
describe("flatten_grammar", []() {
auto get_symbol_sequences = [&](vector<Production> productions) {
return collect(productions, [](Production p) {
return collect(p, [](ProductionStep e) {
return e.symbol;
});
});
};
auto get_precedence_sequences = [&](vector<Production> productions) {
return collect(productions, [](Production p) {
return collect(p, [](ProductionStep e) {
return e.precedence;
});
});
};
auto get_associativity_sequences = [&](vector<Production> productions) {
return collect(productions, [](Production p) {
return collect(p, [](ProductionStep e) {
return e.associativity;
});
});
};
InitialSyntaxGrammar input_grammar{{
// Choices within rules are extracted, resulting in multiple productions.
@ -59,35 +82,10 @@ describe("flatten_grammar", []() {
i_sym(4),
})),
}))
}, {}, {}};
SyntaxGrammar grammar = flatten_grammar(input_grammar);
auto get_symbol_sequences = [&](vector<Production> productions) {
return collect(productions, [](Production p) {
return collect(p, [](ProductionStep e) {
return e.symbol;
});
});
};
auto get_precedence_sequences = [&](vector<Production> productions) {
return collect(productions, [](Production p) {
return collect(p, [](ProductionStep e) {
return e.precedence;
});
});
};
auto get_associativity_sequences = [&](vector<Production> productions) {
return collect(productions, [](Production p) {
return collect(p, [](ProductionStep e) {
return e.associativity;
});
});
};
it("preserves the names and types of the grammar's variables", [&]() {
AssertThat(grammar.variables[0].name, Equals("variable0"));
AssertThat(grammar.variables[1].name, Equals("variable1"));
@ -142,7 +140,7 @@ describe("flatten_grammar", []() {
})));
});
it("associates each symbol with the correct associativity annotation", [&]() {
it("associates each symbol with the correct associativity", [&]() {
Associativity none = AssociativityNone;
AssertThat(

View file

@ -1,5 +1,4 @@
#include "compiler/prepare_grammar/flatten_grammar.h"
#include <string>
#include <vector>
#include <algorithm>
#include "compiler/prepare_grammar/extract_choices.h"
@ -14,7 +13,6 @@ namespace tree_sitter {
namespace prepare_grammar {
using std::find;
using std::string;
using std::vector;
class FlattenRule : public rules::RuleFn<void> {
@ -81,8 +79,8 @@ SyntaxGrammar flatten_grammar(const InitialSyntaxGrammar &grammar) {
vector<Production> productions;
for (const rule_ptr &rule_component : extract_choices(variable.rule)) {
Production production = FlattenRule().flatten(rule_component);
if (std::find(productions.begin(), productions.end(), production) ==
productions.end())
auto end = productions.end();
if (find(productions.begin(), end, production) == end)
productions.push_back(production);
}
result.variables.push_back(