基于C++(QT)实现一个简单的DSL解释器

背景介绍:在硬件产线检测中,需要自动化的读取硬件状态,并逐一判断硬件状态是否健康,如:

temp: 30
signal: 20
lat: 31.123
lng: 118.456
voltage: 4.3
timestamp: 1510381859

最近对于这个需求设计了一个DSL,如:

temp >= 20 && temp <=40
signal >= 15
lat >= 31.0 && lat <=32.0
lng >= 118.0 && lng <= 119.0
timestamp>= time() - 10 && timestamp <= time() + 10

每次工厂产品下线检测只需要设置好对应的DSL脚本,便有产线上位机自动加载并解释执行,以及与硬件串口进行交互检测

#ifndef COMPARATOR_H
#define COMPARATOR_H

#include <QString>
#include <QList>
#include <QDebug>

template <typename T>
class Comparator
{
    typedef T (*F)(const QString &str);
public:

    Comparator(const QString &compType);
    bool compare(const QString &testValue, const QString &expectValue, const QStringList &listValue, F convert);

private:
    QString comp;
    bool compare(const T &leftValue, const T &rightValue);
    bool compare(const T &leftValue, const QList<T> &rightValue);
};

template <typename T>
Comparator<T>::Comparator(const QString &compType):
    comp(compType)
{
}

template <typename T>
bool Comparator<T>::compare(const T &leftValue, const T &rightValue)
{
    if(comp == "!=")
    {
        return leftValue != rightValue;
    }
    else if(comp == "==")
    {
        return leftValue == rightValue;
    }
    else if(comp == ">")
    {
        return leftValue > rightValue;
    }
    else if(comp == ">=")
    {
        return leftValue >= rightValue;
    }
    else if(comp == "<")
    {
        return leftValue < rightValue;
    }
    else if(comp == "<=")
    {
        return leftValue <= rightValue;
    }
    return false;
}

template <typename T>
bool Comparator<T>::compare(const T &leftValue, const QList<T> &rightValue)
{
    if(comp == "in")
    {
        qDebug() << leftValue;
        qDebug() << rightValue;
        return rightValue.contains(leftValue);
    }
    return false;
}

template <typename T>
bool Comparator<T>::compare(const QString &testValue, const QString &expectValue, const QStringList &listValue, F convert)
{
    T testVal = (*convert)(testValue);

    if(listValue.empty())
    {
        T expectVal = (*convert)(expectValue);
        return compare(testVal, expectVal);
    }
    else
    {
        QList<T> expectVal;
        for(const QString &str: listValue)
        {
            expectVal.append((*convert)(str));
        }
        return compare(testVal, expectVal);
    }
}

#endif // COMPARATOR_H