Make Grammar a simple struct

This commit is contained in:
Max Brunsfeld 2016-01-08 15:51:30 -08:00
parent 4b04afac5e
commit 36870bfced
16 changed files with 53 additions and 100 deletions

1
externals/json-parser vendored Submodule

@ -0,0 +1 @@
Subproject commit 70533215eea575e40a0b91a34ae01a779641d73a

View file

@ -27,18 +27,10 @@ rule_ptr prec_right(const rule_ptr &);
rule_ptr prec_right(int precedence, const rule_ptr &);
rule_ptr token(const rule_ptr &rule);
class Grammar {
const std::vector<std::pair<std::string, rule_ptr>> rules_;
std::vector<rule_ptr> extra_tokens_;
std::vector<std::vector<std::string>> expected_conflicts_;
public:
explicit Grammar(const std::vector<std::pair<std::string, rule_ptr>> &);
Grammar &extra_tokens(const std::vector<rule_ptr> &);
Grammar &expected_conflicts(const std::vector<std::vector<std::string>> &);
const std::vector<std::pair<std::string, rule_ptr>> &rules() const;
const std::vector<rule_ptr> &extra_tokens() const;
const std::vector<std::vector<std::string>> &expected_conflicts() const;
struct Grammar {
std::vector<std::pair<std::string, rule_ptr>> rules;
std::vector<rule_ptr> extra_tokens;
std::vector<std::vector<std::string>> expected_conflicts;
};
enum GrammarErrorType {
@ -51,8 +43,11 @@ enum GrammarErrorType {
class GrammarError {
public:
GrammarError(GrammarErrorType type, std::string message);
bool operator==(const GrammarError &other) const;
GrammarError(GrammarErrorType type, std::string message) : type(type), message(message) {}
bool operator==(const GrammarError &other) const {
return type == other.type && message == other.message;
}
GrammarErrorType type;
std::string message;
};

View file

@ -24,7 +24,6 @@
'src/compiler/build_tables/rule_can_be_blank.cc',
'src/compiler/compile.cc',
'src/compiler/generate_code/c_code.cc',
'src/compiler/grammar.cc',
'src/compiler/lex_table.cc',
'src/compiler/parse_table.cc',
'src/compiler/precedence_range.cc',

View file

@ -8,9 +8,9 @@ START_TEST
describe("Compile", []() {
describe("when the grammar's start symbol is a token", [&]() {
it("does not fail", [&]() {
Grammar grammar({
Grammar grammar{{
{ "rule1", str("the-value") }
});
}, {}, {}};
auto result = compile(grammar, "test_grammar");
const GrammarError *error = result.second;
@ -20,9 +20,9 @@ describe("Compile", []() {
describe("when the grammar's start symbol is blank", [&]() {
it("does not fail", [&]() {
Grammar grammar({
Grammar grammar{{
{ "rule1", blank() }
});
}, {}, {}};
auto result = compile(grammar, "test_grammar");
const GrammarError *error = result.second;

View file

@ -12,7 +12,7 @@ ostream &operator<<(ostream &stream, const Grammar &grammar) {
stream << string("#<grammar");
stream << string(" rules: {");
bool started = false;
for (auto pair : grammar.rules()) {
for (auto pair : grammar.rules) {
if (started)
stream << string(", ");
stream << pair.first;

View file

@ -10,11 +10,11 @@ using prepare_grammar::intern_symbols;
describe("intern_symbols", []() {
it("replaces named symbols with numerically-indexed symbols", [&]() {
Grammar grammar({
Grammar grammar{{
{ "x", choice({ sym("y"), sym("_z") }) },
{ "y", sym("_z") },
{ "_z", str("stuff") }
});
}, {}, {}};
auto result = intern_symbols(grammar);
@ -28,9 +28,9 @@ describe("intern_symbols", []() {
describe("when there are symbols that reference undefined rules", [&]() {
it("returns an error", []() {
Grammar grammar({
Grammar grammar{{
{ "x", sym("y") },
});
}, {}, {}};
auto result = intern_symbols(grammar);
@ -39,11 +39,13 @@ describe("intern_symbols", []() {
});
it("translates the grammar's optional 'extra_tokens' to numerical symbols", [&]() {
auto grammar = Grammar({
Grammar grammar{{
{ "x", choice({ sym("y"), sym("z") }) },
{ "y", sym("z") },
{ "z", str("stuff") }
}).extra_tokens({ sym("z") });
}, {
sym("z")
}, {}};
auto result = intern_symbols(grammar);

View file

@ -3,14 +3,14 @@
namespace tree_sitter_examples {
extern const Grammar anonymous_tokens = Grammar({
extern const Grammar anonymous_tokens{{
{ "program", choice({
str("\n"),
str("\r"),
pattern("\\d"),
str("\"hello\"") }) },
}).extra_tokens({
}, {
pattern("\\s"),
});
}, {}};
} // namespace tree_sitter_examples

View file

@ -3,7 +3,7 @@
namespace tree_sitter_examples {
extern const Grammar arithmetic = Grammar({
extern const Grammar arithmetic{{
{ "program", sym("_expression") },
{ "_expression", choice({
@ -37,9 +37,9 @@ extern const Grammar arithmetic = Grammar({
pattern("[0-9]") })) })) },
{ "comment", pattern("#.*") },
}).extra_tokens({
}, {
sym("comment"),
pattern("\\s"),
});
}, {}};
} // namespace tree_sitter_examples

View file

@ -5,7 +5,7 @@ namespace tree_sitter_examples {
// http://slps.github.io/zoo/c/iso-9899-tc3.html
extern const Grammar c = Grammar({
extern const Grammar c{{
{ "translation_unit", repeat(choice({
sym("preproc_define"),
sym("function_definition"),
@ -251,13 +251,13 @@ extern const Grammar c = Grammar({
pattern("[^\\*]"),
pattern("\\*[^/]") })),
str("*/") }) })) },
}).extra_tokens({
}, {
sym("comment"),
pattern("[ \t\r\n]"),
}).expected_conflicts({
}, {
{ "_type_specifier", "_expression" },
{ "_type_specifier", "_expression", "macro_type" },
{ "_type_specifier", "macro_type" },
});
}};
} // namespace tree_sitter_examples

View file

@ -5,7 +5,7 @@ namespace tree_sitter_examples {
// http://slps.github.io/zoo/cpp/iso-n2723.html
extern const Grammar cpp = Grammar({
extern const Grammar cpp{{
{ "translation_unit", repeat(sym("_declaration")) },
{ "_declaration", choice({
@ -211,13 +211,13 @@ extern const Grammar cpp = Grammar({
{ "number", pattern("\\d+(\\.\\d+)?") },
{ "comment", pattern("//[^\n]*") },
}).extra_tokens({
}, {
sym("comment"),
pattern("[ \t\r\n]"),
}).expected_conflicts({
}, {
{ "type_specifier", "_expression" },
{ "template_call", "_expression" },
{ "template_call", "relational_expression" },
});
}};
} // namespace tree_sitter_examples

View file

@ -9,7 +9,7 @@ static rule_ptr terminated(rule_ptr rule) {
str(";") }) });
}
extern const Grammar golang = Grammar({
extern const Grammar golang{{
{ "program", seq({
sym("package_directive"),
repeat(sym("imports_block")),
@ -203,10 +203,10 @@ extern const Grammar golang = Grammar({
{ "comment", pattern("//[^\n]*") },
}).extra_tokens({
}, {
sym("comment"),
sym("_line_break"),
pattern("[ \t\r]"),
});
}, {}};
} // namespace tree_sitter_examples

View file

@ -30,7 +30,7 @@ enum {
PREC_ARGS = 16,
};
extern const Grammar javascript = Grammar({
extern const Grammar javascript{{
{ "program", repeat(sym("_statement")) },
/*
@ -349,13 +349,13 @@ extern const Grammar javascript = Grammar({
str(")"),
sym("statement_block") }) },
}).extra_tokens({
}, {
sym("comment"),
sym("_line_break"),
pattern("[ \t\r]"),
}).expected_conflicts({
}, {
{ "for_in_statement", "_expression" },
{ "method_definition", "_expression" },
});
}};
} // namespace tree_sitter_examples

View file

@ -3,7 +3,7 @@
namespace tree_sitter_examples {
extern const Grammar json = Grammar({
extern const Grammar json{{
{ "_value", choice({
sym("object"),
sym("array"),
@ -22,8 +22,8 @@ extern const Grammar json = Grammar({
{ "null", str("null") },
{ "true", str("true") },
{ "false", str("false") },
}).extra_tokens({
}, {
pattern("\\s"),
});
}, {}};
} // namespace tree_sitter_examples

View file

@ -1,44 +0,0 @@
#include "tree_sitter/compiler.h"
#include "compiler/rule.h"
namespace tree_sitter {
using std::ostream;
using std::pair;
using std::string;
using std::vector;
Grammar::Grammar(const vector<pair<string, rule_ptr>> &rules)
: rules_(rules), extra_tokens_({}) {}
const vector<pair<string, rule_ptr>> &Grammar::rules() const {
return rules_;
}
const vector<rule_ptr> &Grammar::extra_tokens() const {
return extra_tokens_;
}
const vector<vector<string>> &Grammar::expected_conflicts() const {
return expected_conflicts_;
}
Grammar &Grammar::extra_tokens(const vector<rule_ptr> &extra_tokens) {
extra_tokens_ = extra_tokens;
return *this;
}
Grammar &Grammar::expected_conflicts(
const vector<vector<string>> &expected_conflicts) {
expected_conflicts_ = expected_conflicts;
return *this;
}
GrammarError::GrammarError(GrammarErrorType type, string message)
: type(type), message(message) {}
bool GrammarError::operator==(const GrammarError &other) const {
return type == other.type && message == other.message;
}
} // namespace tree_sitter

View file

@ -31,8 +31,8 @@ class InternSymbols : public rules::IdentityRuleFn {
public:
std::shared_ptr<rules::Symbol> symbol_for_rule_name(string rule_name) {
for (size_t i = 0; i < grammar.rules().size(); i++)
if (grammar.rules()[i].first == rule_name)
for (size_t i = 0; i < grammar.rules.size(); i++)
if (grammar.rules[i].first == rule_name)
return make_shared<rules::Symbol>(i);
return nullptr;
}
@ -51,7 +51,7 @@ pair<InternedGrammar, const GrammarError *> intern_symbols(const Grammar &gramma
InternedGrammar result;
InternSymbols interner(grammar);
for (auto &pair : grammar.rules()) {
for (auto &pair : grammar.rules) {
auto new_rule = interner.apply(pair.second);
if (!interner.missing_rule_name.empty())
return { result, missing_rule_error(interner.missing_rule_name) };
@ -61,14 +61,14 @@ pair<InternedGrammar, const GrammarError *> intern_symbols(const Grammar &gramma
new_rule));
}
for (auto &rule : grammar.extra_tokens()) {
for (auto &rule : grammar.extra_tokens) {
auto new_rule = interner.apply(rule);
if (!interner.missing_rule_name.empty())
return { result, missing_rule_error(interner.missing_rule_name) };
result.extra_tokens.push_back(new_rule);
}
for (auto &names : grammar.expected_conflicts()) {
for (auto &names : grammar.expected_conflicts) {
set<rules::Symbol> entry;
for (auto &name : names) {
auto symbol = interner.symbol_for_rule_name(name);

View file

@ -7,7 +7,7 @@
namespace tree_sitter {
class Grammar;
struct Grammar;
class GrammarError;
namespace prepare_grammar {