diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-10-14 01:58:19 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-10-14 01:58:19 +0100 |
commit | 7567f3f24c17dde282a09235a9c43bfc979d17c4 (patch) | |
tree | fc5043b6059001c0512376406467f6ece743c353 /libadhocutil/lexer.cpp | |
parent | Migrate file utils from gentoobrowse-api (diff) | |
download | libadhocutil-7567f3f24c17dde282a09235a9c43bfc979d17c4.tar.bz2 libadhocutil-7567f3f24c17dde282a09235a9c43bfc979d17c4.tar.xz libadhocutil-7567f3f24c17dde282a09235a9c43bfc979d17c4.zip |
Migrate extensible lexer from gentoobrowse-api
Diffstat (limited to 'libadhocutil/lexer.cpp')
-rw-r--r-- | libadhocutil/lexer.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/libadhocutil/lexer.cpp b/libadhocutil/lexer.cpp new file mode 100644 index 0000000..95e079b --- /dev/null +++ b/libadhocutil/lexer.cpp @@ -0,0 +1,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(); + } +} + |