File: inline_simple_visitor.cpp

package info (click to toggle)
foundry 0.0.20130809-2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 632 kB
  • ctags: 2,340
  • sloc: cpp: 6,376; yacc: 366; makefile: 192; lex: 184
file content (75 lines) | stat: -rw-r--r-- 1,978 bytes parent folder | download
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;
}

}
}