假设我想用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&amp;)。 我不清楚如何通过std :: string迭代boost正则表达式。
我希望有人可以帮助我!
答案 0 :(得分:1)
假设Boost regexp使用与标准C ++库中的正则表达式类似的方法(我意识到标准中的那些基于来自Boost的提议,但其他组件并不完全相同),您将使用在std::match_results<...>
对象中获取的信息,用于确定与匹配相关的信息。
答案 1 :(得分:0)
对于有兴趣的人。我在当前的实现中以这种方式解决了它:
请注意,关键部分可能会丢失,但这回答了问题
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.");
}
}