用Javascript解析逻辑表达式

用Javascript解析逻辑表达式,javascript,parsing,logic,expression,Javascript,Parsing,Logic,Expression,我正在构建一个逻辑表达式解析器。我非常喜欢mongoDB构造逻辑语句的方式。但是,我想这是否是存储和解析逻辑表达式的最佳结构 const logicPayload = [ { varA: { $eq: "meow" } }, { $and: [{ varB: { $lt: "varD" } }, { varB: { $gte: "varC" } }] }, { $not: [{ varB: { $eq: "varA" } }] } ]; 考虑到上面的负载,我如何设计一个函数来解析表

我正在构建一个逻辑表达式解析器。我非常喜欢mongoDB构造逻辑语句的方式。但是,我想这是否是存储和解析逻辑表达式的最佳结构

const logicPayload = [
  { varA: { $eq: "meow" } },
  { $and: [{ varB: { $lt: "varD" } }, { varB: { $gte: "varC" } }] },
  { $not: [{ varB: { $eq: "varA" } }] }
];
考虑到上面的负载,我如何设计一个函数来解析表达式
varA
varB
varC
varD
将在运行时解析

下面是一个虚拟解析函数

const resovleValue = varID => {
  switch (varID) {
    case "varA":
      return "meow";
      break;
    case "varB":
      return 100;
    case "varC":
      return 100;
    case "varD":
      return 983;
  }
};
我试图创建下面的逻辑函数

/**
 * This logic function must only return true or false
 */
const logicFunction = logicPayload => {};

非常感谢您的指导。谢谢

这里有一个逻辑解析器,它使用递归来处理逻辑的内部数组

一旦找到返回false的规则,它将停止处理

函数检查规则(规则){
设key1=Object.keys(规则)[0];
设comp=Object.values(规则)[0];
如果(/^[$](和|或|否)$/.test(键1)和&Array.isArray(comp)){
设aon=key1;
让规则=补偿;
让结果=[];
(规则汇编){
设valid=checkRule(r);
结果:推送(有效);
//log(`${aon}${JSON.stringify(r)}:${valid}`);
如果(aon=='$and'&&&!valid)返回false;
if(aon=='$或'&&valid)返回true;
if(aon==='$not'&&valid)返回false;
}
//console.log(JSON.stringify(results));
如果(aon=='$and'&&results.some((x)=>!x))
返回false;
if(aon=='$or'&&results.every((x)=>!x))
返回false;
if(aon=='$not'&&results.some((x)=>x))
返回false;
}
否则{
让运算符=对象键(comp)[0];
设key2=comp[操作员];
设val1=resolveValue(键1)| |键1;
设val2=resolveValue(key2)| | key2;
//log(`t${val1}${operator}${val2}`);
开关(操作员){
案例“$eq”:
如果(!(val1==val2))返回false;
打破
案例“$ne”:
案例“$neq”:
如果(!(val1!=val2))返回false;
打破
案例“$lt”:
如果(!(val1=val2))返回false;
打破
违约:
返回false;
}
}
返回true;
}
功能逻辑功能(逻辑有效负载){
让结果=[];
for(逻辑有效载荷规则){
let valid=checkRule(规则);
//log(`${valid}:${JSON.stringify(rule)}`);
结果:推送(有效);
如果(!valid)返回false;
}
返回结果。每((x)=>x);
};
常量解析值=(变量)=>{
开关(可变){
案例“varA”:返回“meow”;
案例“varB”:返回100;
案例“varC”:返回100;
案例“varD”:返回983;
}
};
让逻辑有效载荷=[
{varA:{$eq:“喵”},
{$和:[
{varB:{$lt:“varD”},
{varB:{$gte:“varC”}
] },
{$not:[{varB:{$eq:varA}]}
];
让结果=逻辑功能(逻辑有效载荷);
控制台日志(结果);

感谢您的快速响应和全面回答。我想问一下,关于使用当前有效负载与将其更改为此
const logicPayload=[[varA,$eq,“$meow”]、[“$and”、[[varB,$lt,“$varD”]、varB,“$gte”,“varC”]]、[“$or”、[varB,$notEq”,varA]、[varC,$gt”,varD]
我想知道哪种结构更好,为什么。感谢guidanceWell,在当前版本中,它会检查它是否是数组,以查看它是否是$and/$not/$or。所以你必须使用另一个技巧。应该可以,例如,检查第一个元素中是否有
$
。顺便说一句,我注意到在logicPayload中很难知道它是字符串还是变量。F.e.如果你有一个“meow”变量呢?实际上,在ES6兼容的代码中,你可以用它来表示方程。但我猜您更多地是在寻找一种可以作为JSON字符串发送的格式。因为这两种方法都是可能的,您认为这更简单、更好。如果阵列或对象工作得更好,如何访问。关于logicPayload中的变量(键),我正在检查它是否是mongoID字符串。因此,所有变量都需要传递
ObjectId.isValid(variable)
,这就是为什么我们有另一个函数通过查询mongo数据库来解析变量。我发现第一个函数,使用数组中的对象,更具可读性。