0

単純なプログラミング言語をブースト正規表現で解析したいとしましょう。

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 を介してブースト正規表現を反復する方法が明確ではありません。

誰かが私を助けてくれることを願っています!

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 に答える