Added optimize_nodes parameter.

This commit is contained in:
yhirose 2015-06-12 14:09:23 -04:00
parent 1a9fddd3f8
commit 341659f699
3 changed files with 15 additions and 12 deletions

View File

@ -73,7 +73,7 @@ peg& get_parser()
throw logic_error("invalid peg grammar"); throw logic_error("invalid peg grammar");
} }
parser.enable_ast({ parser.enable_ast(true, {
/* /*
Definition, Tag Optimize Definition, Tag Optimize
---------------------- ------------------ ---------- */ ---------------------- ------------------ ---------- */

View File

@ -27,6 +27,7 @@ bool read_file(const char* path, vector<char>& buff)
int main(int argc, const char** argv) int main(int argc, const char** argv)
{ {
auto opt_ast = false; auto opt_ast = false;
auto opt_optimize_ast_nodes = false;
auto opt_help = false; auto opt_help = false;
vector<const char*> path_list; vector<const char*> path_list;
@ -37,13 +38,15 @@ int main(int argc, const char** argv)
opt_help = true; opt_help = true;
} else if (string("--ast") == arg) { } else if (string("--ast") == arg) {
opt_ast = true; opt_ast = true;
} else if (string("--optimize_ast_nodes") == arg || string("--opt") == arg) {
opt_optimize_ast_nodes = true;
} else { } else {
path_list.push_back(arg); path_list.push_back(arg);
} }
} }
if (path_list.empty() || opt_help) { if (path_list.empty() || opt_help) {
cerr << "usage: peglint [--ast] [grammar file path] [source file path]" << endl; cerr << "usage: peglint [--ast] [--optimize_ast_nodes|--opt] [grammar file path] [source file path]" << endl;
return 1; return 1;
} }
@ -86,7 +89,7 @@ int main(int argc, const char** argv)
}; };
if (opt_ast) { if (opt_ast) {
peg.enable_ast(); peg.enable_ast(opt_optimize_ast_nodes);
std::shared_ptr<peglib::Ast> ast; std::shared_ptr<peglib::Ast> ast;
if (!peg.parse_n(source.data(), source.size(), ast)) { if (!peg.parse_n(source.data(), source.size(), ast)) {

View File

@ -2041,19 +2041,19 @@ public:
struct AstNodeInfo { struct AstNodeInfo {
const char* name; const char* name;
int tag; // TODO: It should be calculated at compile-time from 'name' with constexpr hash function. int tag; // TODO: It should be calculated at compile-time from 'name' with constexpr hash function.
bool optimize; bool optimize_nodes;
}; };
peg& enable_ast(std::initializer_list<AstNodeInfo> list) { peg& enable_ast(bool optimize_nodes, std::initializer_list<AstNodeInfo> list) {
for (const auto& info: list) { for (const auto& info: list) {
ast_node(info); ast_node(info);
} }
ast_end(); ast_end(optimize_nodes);
return *this; return *this;
} }
peg& enable_ast() { peg& enable_ast(bool optimize_nodes = true) {
ast_end(); ast_end(optimize_nodes);
return *this; return *this;
} }
@ -2080,7 +2080,7 @@ private:
if (is_token) { if (is_token) {
return std::make_shared<Ast>(info.name, info.tag, std::string(sv.s, sv.n)); return std::make_shared<Ast>(info.name, info.tag, std::string(sv.s, sv.n));
} }
if (info.optimize && sv.size() == 1) { if (info.optimize_nodes && sv.size() == 1) {
std::shared_ptr<Ast> ast = sv[0].get<std::shared_ptr<Ast>>(); std::shared_ptr<Ast> ast = sv[0].get<std::shared_ptr<Ast>>();
return ast; return ast;
} }
@ -2088,18 +2088,18 @@ private:
}; };
} }
void ast_end() { void ast_end(bool optimize_nodes) {
for (auto& x: *grammar_) { for (auto& x: *grammar_) {
const auto& name = x.first; const auto& name = x.first;
auto& rule = x.second; auto& rule = x.second;
auto& action = rule.actions.front(); auto& action = rule.actions.front();
if (!action) { if (!action) {
auto is_token = rule.is_token; auto is_token = rule.is_token;
action = [name, is_token](const SemanticValues& sv) { action = [=](const SemanticValues& sv) {
if (is_token) { if (is_token) {
return std::make_shared<Ast>(name.c_str(), AstDefaultTag, std::string(sv.s, sv.n)); return std::make_shared<Ast>(name.c_str(), AstDefaultTag, std::string(sv.s, sv.n));
} }
if (sv.size() == 1) { if (optimize_nodes && sv.size() == 1) {
std::shared_ptr<Ast> ast = sv[0].get<std::shared_ptr<Ast>>(); std::shared_ptr<Ast> ast = sv[0].get<std::shared_ptr<Ast>>();
return ast; return ast;
} }