c_cpp 嵌套一堆托架

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 嵌套一堆托架相关的知识,希望对你有一定的参考价值。

#include <functional>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <tuple>
#include <utility> // for pair
#include <vector>
using namespace std;

class parser
{
public:
    parser(const vector<pair<string, string>> &bracket_pairs) :
        m_syntax(build_syntax(bracket_pairs))
    {
    }

    void parse(const string &expr) const
    {
        stack<unsigned int> s;
        size_t pos = 0;

        foreach_symbol(expr, [&](const symbol_info &info)
        {
            pos++;
            if (info.id == 0) return;

            if (info.begin)
            {
                s.push(info.id);
            }
            else
            {
                if (s.empty() || s.top() != info.id) throw pos;
                s.pop();
            }
        });

        if (s.size() > 0) throw pos + 1;
    }

private:
    enum { MAX_SYMBOL_LEN = 2 };

    struct symbol_info
    {
        unsigned int id; // 0 is preserved for symbols that not predefined.
        bool begin;
    };

    map<string, symbol_info> m_syntax;

private:
    void foreach_symbol(const string &expr, function<void(const symbol_info &)> yield) const
    {
        for (size_t i = 0, step; i < expr.length(); i += step)
        {
            symbol_info info;
            tie(info, step) = foreach_symbol_subroutine(expr, i);
            yield(info);
        }
    }

    tuple<symbol_info, size_t> foreach_symbol_subroutine(const string &expr, size_t i) const
    {
        for (size_t len = MAX_SYMBOL_LEN; len > 0; len--)
        {
            auto token = expr.substr(i, len);
            try
            {
                return { m_syntax.at(token), token.length() };
            }
            catch (const out_of_range &ex)
            {
            }
        }
        return { symbol_info{ 0, false }, 1 };
    }

    static map<string, symbol_info> build_syntax(const vector<pair<string, string>> &bracket_pairs)
    {
        map<string, symbol_info> syntax;

        unsigned int id = 1;
        for (auto &bracket_pair : bracket_pairs)
        {
            int count = 0;
            for (auto &symbol : { bracket_pair.first, bracket_pair.second })
            {
                syntax[symbol] = symbol_info{ id, (0 == count++) };
            }
            id++;
        }
        return syntax;
    }
};

void parse_expr(const string &expr)
{
    static const parser p551({
        { "(", ")" },
        { "[", "]" },
        { "{", "}" },
        { "<", ">" },
        { "(*", "*)" }
    });

    p551.parse(expr);
}

int main()
{
    string expr;
    while (getline(cin, expr))
    {
        try
        {
            parse_expr(expr);
            cout << "YES" << endl;
        }
        catch (size_t position)
        {
            cout << "NO " << position << endl;
        }
    }
    return 0;
}

以上是关于c_cpp 嵌套一堆托架的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 视图控制器支持嵌套的故事板加载

c_cpp 使用一堆C ++ 11/14特性和“老派”C ++开发人员的单一函数甚至不再像C ++那样阅读.Specificall

更换托架空间

c_cpp 一种解析调用pantry解析的新方法,可用于解析非嵌套语言。

json 用于托架的Jasmine Snippets

使用属性树在 boost 中解析 xml