nancy.liao
1 天以前 11f2f2e329ef404d0e9c022cb2f9fbbb45bae285
libscpi/inc/scpi/externinterface.h
@@ -1,253 +1,34 @@
#ifndef EXTERNINTERFACE_H
#define EXTERNINTERFACE_H
#include <iostream>
#include<vector>
//这个类用在做SCPI命令的语法分析,会将词法匹配的结果返回给SCPI库
#ifdef __cplusplus
extern "C"
{
#endif
namespace SCPIPASER
typedef struct
{
class Segment {
public:
    //必填
    bool is_required = false;
    //变量 [:Measure] 这种的为变量 会置为TRUE
    bool is_variable = false;
    //是否有嵌套形式
    bool is_nested = false;
    // 可选组的数量
    int variableSize = 0;
    std::vector<std::string> options;
    // std::vector<Segment> sub_segments; // 用于存储嵌套的可选组
};
    int is_required;
    int is_variable;
    int is_nested;
    int variableSize;
    char** options;
    int options_count;
} CSegment;
class PatternParser
typedef struct
{
private:
    static void trim_whitespace(std::string& str)
    {
        auto not_space = [](int ch) { return !std::isspace(ch); };
        str.erase(str.begin(), std::find_if(str.begin(), str.end(), not_space));
        str.erase(std::find_if(str.rbegin(), str.rend(), not_space).base(), str.end());
    }
    static std::vector<std::string> split_options(const std::string& input) {
        std::vector<std::string> result;
        size_t start = 0;
        size_t end = input.find('|');
        while (end != std::string::npos) {
            std::string token = input.substr(start, end - start);
            trim_whitespace(token);
            //token = remove_colon(token); // 移除冒号
            if (!token.empty()) result.push_back(token);
            start = end + 1;
            end = input.find('|', start);
        }
        std::string last_token = input.substr(start);
        trim_whitespace(last_token);
        last_token = remove_colon(last_token); // 移除冒号
        if (!last_token.empty()) result.push_back(last_token);
        return result;
    }
    static std::string remove_colon(const std::string& input) {
        std::string result;
        for (char ch : input) {
            if (ch != ':') {
                result += ch;
            }
        }
        return result;
    }
public:
    static std::vector<std::string> parse_input_data(const std::string& input)
    {
        std::vector<std::string> result;
        size_t start = 0;
        size_t end = input.find(':');
        while (end != std::string::npos)
        {
            result.push_back(input.substr(start, end - start));
            start = end + 1;
            end = input.find(':', start);
        }
        result.push_back(input.substr(start));
        return result;
    }
    static bool match_all_segments(std::vector<std::string> stringList, std::vector<Segment> vecSegment)
    {
        int currentIndex = 0;
        for (int i =0;i<vecSegment.size();i++)
        {
            auto currentSegment = vecSegment[i];
            //严格匹配
            if (currentSegment.is_required)
            {
                for (auto option : currentSegment.options)
                {
                    if (stringList[currentIndex] != option)
                    {
                        //std::cout << "参数匹配失败  " << stringList[currentIndex] << "   option :  " << option;
                        return false;
                    }
                    else
                    {
                        //std::cout << "参数匹配成功 " << stringList[currentIndex] << "   option :  " << option<<std::endl;
                        currentIndex += 1;
                    }
                    break;
                }
            }
            //可选组
            else if (currentSegment.is_variable)
            {
                //如果有可选组的情况下 且参数长度一直 则匹配可选项内容 否则的话跳过
                if (stringList.size() == vecSegment.size())
                {
                    auto vecTempSegments = currentSegment.options;
                    for (auto option : vecTempSegments)
                    {
                        if (stringList[currentIndex] != option)
                        {
                            //std::cout << "参数匹配失败  " << stringList[currentIndex] << "   option :  " << option;
                            return false;
                        }
                        else
                        {
                            //std::cout << "参数匹配成功 " << stringList[currentIndex] << "   option :  " << option << std::endl;
                            currentIndex += 1;
                        }
                        break;
                    }
                }
            }
            //可变参
            else
            {
                //std::cout << "可变参数: "<< stringList[currentIndex] << " " << currentSegment.options[0] << std::endl;
                currentIndex += 1;
            }
        }
        return true;
    }
    CSegment* segments;
    int segments_count;
} CPatternResult;
    static std::vector<Segment> extract_all_segments(const std::string& pattern)
    {
        std::vector<Segment> segments;
        size_t pos = 0;
        const size_t len = pattern.length();
        while (pos < len)
        {
            while (pos < len && std::isspace(pattern[pos])) ++pos;
            if (pos >= len) break;
            if (pattern[pos] == '<') {
                size_t end_pos = pattern.find('>', pos);
                if (end_pos == std::string::npos) break;
                std::string content = pattern.substr(pos + 1, end_pos - pos - 1);
                trim_whitespace(content);
                Segment segment;
                segment.is_variable = false; // `<...>` 不被视为变量
                segment.options = split_options(content);
                // 检查是否包含 `:`
                if (content.find(':') != std::string::npos) {
                    segment.is_required = true; // 如果包含 `:`
                }
                else {
                    segment.is_required = false; // 如果不包含 `:`
                }
                segments.push_back(segment);
                pos = end_pos + 1;
            }
            else if (pattern[pos] == '[')
            {
                size_t end_pos = pattern.find(']', pos);
                if (end_pos == std::string::npos) break;
                std::string content = pattern.substr(pos + 1, end_pos - pos - 1);
                trim_whitespace(content);
                Segment segment;
                segment.variableSize += 1;
                segment.is_required = false;
                segment.is_variable = true;
                segment.options = split_options(content);
                segments.push_back(segment);
                pos = end_pos + 1;
            }
            else
            {
                size_t next_lt = pattern.find('<', pos);
                size_t next_lb = pattern.find('[', pos);
                size_t next_special = std::min(next_lt, next_lb);
                std::string content;
                if (next_special != std::string::npos)
                {
                    content = pattern.substr(pos, next_special - pos);
                }
                else
                {
                    content = pattern.substr(pos);
                }
                trim_whitespace(content);
                if (!content.empty())
                {
                    // 用 ':' 拆分参数
                    size_t start = 0;
                    size_t end = content.find(':');
                    while (end != std::string::npos)
                    {
                        std::string token = content.substr(start, end - start);
                        trim_whitespace(token);
                        if (!token.empty())
                        {
                            Segment segment;
                            segment.is_required = true; // 明确标记为必填项
                            segment.is_variable = false; // 普通文本不视为变量
                            segment.options.push_back(token);
                            segments.push_back(segment);
                        }
                        start = end + 1;
                        end = content.find(':', start);
                    }
                    // 处理最后一个部分
                    std::string last_token = content.substr(start);
                    trim_whitespace(last_token);
                    if (!last_token.empty())
                    {
                        Segment segment;
                        segment.is_required = true;
                        segment.is_variable = false;
                        segment.options.push_back(last_token);
                        segments.push_back(segment);
                    }
                }
                pos = (next_special != std::string::npos) ? next_special : len;
            }
        }
        return segments;
    }
};
}
int match_segments_global(const char* input, int pattern_index);
void parse_pattern_global(const char* pattern);
int get_pattern_count();
void clear_global_patterns();
#ifdef __cplusplus
}
#endif
#endif // EXTERNINTERFACE_H