javascript - 如何使用 Javascript 将字符串转换为 AST 对象?
问题描述
我需要将字符串转换为遵守特定语法规则的对象(类似 AST)。
我基本上有 3 种类型的表达式 ( '@', '$' and '#'
)。'#' 类型的表达式写成,#something
而其他两个写成@something==somethingelse
and $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'
}]
}
]
};
解决方案
虽然会有特定于您的情况的细微差别,虽然听起来很明显,但它可能有助于将问题分解为更易于管理的部分。
这个问题的一大块将是你的表达式字符串的解析和随后的标记化。首先编写一些代码,这些代码可以接受类似的字符串#something
并将其转换为中间数据结构,以后可以利用该结构来执行与构建 AST 相关的更具体的任务。这个想法是您希望将最简单的可能工作的东西包装到一个黑盒中,使您能够以增量和可靠的方式改进/更改/添加功能。一开始尽量不要过度设计,只添加与当前手头任务相关的功能,以避免陷入分析瘫痪陷阱。
一旦您在标记化步骤上进行了一些迭代,您就可以开始考虑下一个阶段,即为您的 AST 实现访问者/步行者。我有信心说您的设计会随着您完成此过程而发展,因此设计您的代码以进行更改至关重要 - 这应该包括可测试性作为主要考虑因素。
虽然它不是 javascript,但这个基于 C#/Roslyn 的项目(完全披露:我是该存储库的作者/维护者)非常接近地展示了您所询问的功能类型。高温高压
推荐阅读
- android - 如何在 React 中使容器/包装器视图可点击
- typescript - 在 Typescript 中,你可以用不同的泛型类型两次实现相同的泛型接口吗?
- mysql - mysql Aurora中upsert的性能问题
- sql - SQL Server:基于 Json 数组中的值的 Json 列查询/选择
- spring-boot - 无法将数据作为隐藏字段从 html 发送到控制器
- python - 如何将异步函数传递给 Python 中的线程目标?
- python - Pandas - 根据列中的排序顺序拆分数据帧
- php - 调用数组上的成员函数 num_rows() 如何解决此错误
- visual-studio-code - VSCode 工作区自动包含所有子文件夹
- python - 在数据库表中加载一个 spark sql 表