blob: 95e079bf5237df008d0e54410728e6b00873a12d (
plain)
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
76
77
78
|
#include "lexer.h"
namespace AdHoc {
const Lexer::State Lexer::InitialState = "";
Lexer::Lexer()
{
}
Lexer::Lexer(const Rules & r) : rules(r)
{
}
void
Lexer::extract(const gchar * string, size_t length) const
{
ExecuteState es;
while (es.position < length) {
const Rule * selected = nullptr;
for (const auto & r : rules) {
const auto & s = boost::get<0>(r);
if (s.find(es.getState()) == s.end()) {
continue;
}
const auto & p = boost::get<1>(r);
if (p->matches(string, length, es.position)) {
selected = &r;
break;
}
}
if (!selected) {
throw std::runtime_error(std::string("Unexpected input in state (" + es.getState() + ") at ") + (string + es.position));
}
es.pattern = boost::get<1>(*selected);
const auto & h = boost::get<2>(*selected);
h(&es);
es.position += es.pattern->matchedLength();
}
}
Lexer::ExecuteState::ExecuteState() :
position(0)
{
stateStack.push_back(InitialState);
}
void
Lexer::ExecuteState::setState(const State & s)
{
stateStack.back() = s;
}
void
Lexer::ExecuteState::pushState(const State & s)
{
stateStack.push_back(s);
}
void
Lexer::ExecuteState::popState()
{
stateStack.pop_back();
}
const Lexer::State &
Lexer::ExecuteState::getState() const
{
return stateStack.back();
}
size_t
Lexer::ExecuteState::depth() const
{
return stateStack.size();
}
}
|