基于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