0

假设我想用 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&)。我不清楚如何通过 std::string 使用 boost 正则表达式进行迭代。

我希望有一个人可以帮助我!

4

2 回答 2

1

假设 Boost 正则表达式使用与标准 C++ 库中的正则表达式类似的方法(我意识到标准中的那些是基于来自 Boost 的提议,但其他组件并不完全相同),您将使用获得的信息在std::match_results<...>对象中确定与匹配相关的信息。

于 2012-11-18T16:44:30.410 回答
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.");
    }
}
于 2012-11-21T10:33:24.930 回答