Boost.Regex парсинг

Допустим, я хочу разобрать простой язык программирования с регулярными выражениями boost.

import a
import b

class c

Теперь я хочу иметь такой макет:

#include <string>
#include <boost/filesystem.hpp>
#include <exception>

using namespace std;
using namespace boost;
using namespace boost::filesystem;

class parser
{
string _source;
unsigned int pos;
public:
parser(const string& source) : _source(source), pos(0) {}

string expect(const regex& expr)
{
string s = next(expr)
if (s != "")
return s;
else
{
--pos;
throw exception("Expected another expression.");
}
}

string next(const regex& expr)
{
// Removing all whitespace before first non-whitespace character
// Check if characters 0 till x matches regex expr
// Return matched string of "" if not matched.
}

bool peek(const regex& expr);

parse()
{
regex identifier("\a*");
if (peek("import"))
string package = expect(identifier);
else if (peek("class"))
string classname = expect(identifier);
}
};

Теперь мне нужна ваша помощь, чтобы определить функцию parser :: next (const regex)&).
Мне не понятно, как выполнять итерации с регулярным выражением boost через std :: string.

Я надеюсь, что кто-то может помочь мне!

0

Решение

Предполагая, что в регулярном выражении Boost используется аналогичный подход, как в регулярных выражениях стандартной библиотеки C ++ (я понимаю, что в стандарте основаны на предложении, полученном из Boost, но другие компоненты не полностью идентичны), вы будете использовать полученную информацию в std::match_results<...> Объект для определения информации, связанной с совпадением.

1

Другие решения

Для людей, которые заинтересованы. Я решил это так в текущей реализации:

Обратите внимание, что важные части могут отсутствовать, но это отвечает на вопрос

int submatch(const std::string& input, const regex& e)
{
boost::match_results<std::string::const_iterator> what;
if(0 == boost::regex_match(input, what, e, boost::match_default | boost::match_partial))
{
// the input so far could not possibly be valid so reject it:
return 0;
}
// OK so far so good, but have we finished?
if(what[0].matched)
{
// excellent, we have a result:
return 2;
}
// what we have so far is only a partial match...
return 1;
}

void skip_ws()
{
// Skip all whitespaces
regex ws("\\s");
while ((pos < (source.length() - 1)) && boost::regex_match(source.substr(pos++, 1), ws))
{
}
pos -= 1;
}

string lex(const token& t)
{
skip_ws();
string sub;

unsigned int subpos = pos;
bool matched = false;
while (subpos < (source.length() - 1))
{
sub.push_back(source[subpos++]);
int result = submatch(sub, t.expr);
if (result == 1) // Partial
{
continue;
}
else if (result == 2)
{

matched = true;
continue;
}
else if (result == 0) // No match
{
if (matched)
{
sub.erase(sub.end()-1);
subpos -= 1;
break;
}
else
{
return "";
}
}
}

return sub;
}

string expect(const token& t)
{
cout << " string expect(\"" << t.expr << "\")";
string s = lex(t);
pos += s.length();
if (s != "")
{
cout << endl;
return s;
}
else
{
--pos;
cout << "-> False" << endl;
throw string("Expected another expression.");
}
}
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector