如何使用Javascript将字符串转换为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 &&

我需要将一个字符串转换成一个对象(类似AST),遵守特定语法中的规则

我基本上有三种类型的表达式(
“@”,“$”和“#”
)。类型为“#”的表达式写为
#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'
            }]
        }
    ]
};