如何使用Javascript将字符串转换为AST对象?
我需要将一个字符串转换成一个对象(类似AST),遵守特定语法中的规则 我基本上有三种类型的表达式(如何使用Javascript将字符串转换为AST对象?,javascript,parsing,compiler-construction,abstract-syntax-tree,Javascript,Parsing,Compiler Construction,Abstract Syntax Tree,我需要将一个字符串转换成一个对象(类似AST),遵守特定语法中的规则 我基本上有三种类型的表达式(“@”,“$”和“#”)。类型为“#”的表达式写为#something,而其他两个表达式写为@something==somethingelse和$something==somethingelse 这些表达式可以使用连词(“and”、“or”)进行分组,并且可以使用括号修改操作顺序 以下是完整表达式的示例: const expression = `#buy &&
“@”,“$”和“#”
)。类型为“#”的表达式写为#something
,而其他两个表达式写为@something==somethingelse
和$something==somethingelse
这些表达式可以使用连词(“and”、“or”
)进行分组,并且可以使用括号修改操作顺序
以下是完整表达式的示例:
const expression =
`#buy
&& (@car == white || @bike == blue)
&& $user==authenticated`;
我正在寻找一种方法,使用javascript或基于javascript的工具(将在React项目中使用)将其转换为下面的对象(类似AST)
虽然你的情况会有一些细微差别,尽管听起来很明显,但这可能有助于将问题分解成更易于管理的部分 这个问题的一部分是表达式字符串的解析和后续标记化。首先编写一些代码,这些代码可以将字符串(如
#something
)转换为中间数据结构,以后可以利用它执行与构建AST相关的更具体的任务。其想法是,您希望将可能工作的最简单的事情封装到一个黑匣子中,该黑匣子允许您以增量和可靠的方式改进/更改/添加功能。一开始不要过度设计,只添加与当前任务相关的功能,以避免陷入分析瘫痪的陷阱
一旦您完成了标记化步骤的一些迭代,您就可以开始考虑下一个阶段,即为您的AST实现一个访问者/行者。我有信心地说,您的设计将随着这个过程的进行而不断发展,因此,为更改而设计代码是至关重要的,这应该包括可测试性作为主要考虑因素
虽然它不是javascript(完全公开:我是该repos的作者/维护者),但它非常接近地展示了您所询问的功能类型。HTH虽然我确实发现这个问题引起了我的好奇心,但我觉得它在“当前状态下是不可回答的,因为这个问题的解决方案非常庞大-你在问如何实现自定义DSL解释器/渲染器,这通常是非常厚的教科书的主题!”)是否有一些方法可以帮助您做出决定,或者更具体的方法?到目前为止,我已经尝试用两种不同的方法来解决这个问题。1) 使用正则表达式,我发现自己掉进了一个兔子洞。2) 使用基于Java的ANTLR工具,但可以用javascript生成访问者。我一直在寻找如何解决这一问题的想法,而不仅仅是一个具体的解决方案,尽管最新的解决方案将受到赞赏。:)谢谢你的补充信息。希望我的回答能提供你想要的指导!OP想要解析表达式。这远没有构建完整的DSL那么难,也不需要复杂的机器。他应该看看我关于如何构建递归下降解析器的讨论,其中还讨论了如何作为解析过程的一部分构建AST。按照我的例子,他可以很容易地用JavaScript编写代码。谢谢你的链接,@Ira Baxter。OP请求“如何解决这个问题而不是一个特定的解决方案”,如果您能详细说明“构建一个完整的DSL”是什么意思,我会很感激的。您不认为表达式语法是DSL吗?“中间数据结构”将在许多方面与您的DSL等同于HTML DOM。尝试在你最熟悉的工具和框架中寻找熟悉的模式,然后窃取它们的想法和方法!
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'
}]
}
]
};