我需要遵循特定语法的规则,将字符串转换为对象(类似AST)。
我基本上有3种类型的表达式('@', '$' and '#'
)。类型为#的表达式写为#something
,而其他两个表达式写为@something==somethingelse
和$something==somethingelse
。
可以使用连词('and', 'or'
)对这些表达式进行分组,并且可以使用括号来修改操作顺序。
以下是一个完整表达式的示例:
const expression =
`#buy
&& (@car == white || @bike == blue)
&& $user==authenticated`;
我正在寻找一种使用javascript或基于javascript的工具(将在React项目中使用)将其转换为以下对象(如AST的对象)的方法。
const ast = {
type: 'expression',
conjunction: 'null',
expressions: [{
type: 'expression',
conjunction: null,
expressions: [{
type: '#',
left: 'buy',
operator: null,
right: null
}]
},
{
type: 'expression',
conjunction: '&&',
expressions: [{
type: 'expression',
conjunction: 'null',
expressions: [{
type: '@',
left: 'car',
operator: '==',
right: 'white'
}]
},
{
type: 'expression',
conjunction: '||',
expressions: [{
type: '@',
left: 'bike',
operator: '==',
right: 'blue'
}]
}
]
},
{
type: 'expression',
conjunction: '&&',
expressions: [{
type: '$',
left: 'user',
operator: '==',
right: 'authenticaded'
}]
}
]
};
答案 0 :(得分:-1)
虽然您的情况可能会有细微差别,尽管听起来很明显,但这可能有助于将问题分解为更易于管理的部分。
此问题的一大块将是表达式字符串的解析和随后的标记化。首先编写一些代码,这些代码可以使用#something
之类的字符串,然后将其转换为中间数据结构,以后可以利用它来执行与构造AST有关的更具体的任务。这个想法是,您希望将可能工作的最简单的东西包装到一个黑盒子中,该盒子允许您逐步和可靠地改进/更改/添加功能。首先不要尝试过度设计,而仅添加与当前手头任务相关的功能,以避免陷入分析瘫痪陷阱。
一旦在标记化步骤上做了一些迭代,就可以开始考虑下一个阶段,这是AST的Visitor / Walker的实现。我很自信地说您的设计会随着这个过程的发展而不断发展,因此,为变更而设计代码至关重要—这应将可测试性作为主要考虑因素。
尽管不是JavaScript,corresponding docker image and uploaded it to the dockerhub(完整披露:我是该回购协议的作者/维护者)非常接近地演示了您所要求的功能类型。 HTH