1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "inline_simple_visitor.h"
#include "errors.h"
namespace foundry {
namespace parse {
void inline_simple_visitor::visit(foundry::parse::string_literal&) { }
void inline_simple_visitor::visit(foundry::parse::unresolved_symbol &)
{
throw internal_error("Unresolved symbol found during inlining");
}
void inline_simple_visitor::visit(foundry::parse::terminal&) { }
void inline_simple_visitor::visit(foundry::parse::nonterminal &nt)
{
if(is_simple_rule(nt.rule))
*current_component_context = nt.rule->alternatives.front()->group->components.front();
}
void inline_simple_visitor::visit(foundry::parse::regex&) { }
void inline_simple_visitor::visit(foundry::parse::group &)
{
is_simple = false;
}
void inline_simple_visitor::visit(foundry::parse::root &r)
{
if(r.rules.empty())
return;
start = r.rules.front();
for(auto &i : r.rules)
{
current_rule_context = &i;
descend(i);
}
r.rules.remove_if(std::bind(std::mem_fun(&inline_simple_visitor::is_simple_rule), this, std::placeholders::_1));
}
void inline_simple_visitor::visit(foundry::parse::rule &r) { descend(r.alternatives); }
void inline_simple_visitor::visit(foundry::parse::alternative &a)
{
for(auto &i : a.group->components)
{
current_component_context = &i;
descend(i);
}
}
bool inline_simple_visitor::is_simple_rule(rule_ptr &r)
{
if(r == start)
return false;
if(r->alternatives.size() == 1 &&
r->alternatives.front()->group->rep == repeat_none &&
r->alternatives.front()->group->components.size() == 1)
{
is_simple = true;
descend(r->alternatives.front()->group->components.front());
return is_simple;
}
return false;
}
}
}
|