如何使用Javascript将字符串转换为AST对象?

时间:2018-10-05 16:06:47

标签: javascript parsing compiler-construction abstract-syntax-tree

我需要遵循特定语法的规则,将字符串转换为对象(类似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'
            }]
        }
    ]
};

1 个答案:

答案 0 :(得分:-1)

虽然您的情况可能会有细微差别,尽管听起来很明显,但这可能有助于将问题分解为更易于管理的部分。

此问题的一大块将是表达式字符串的解析和随后的标记化。首先编写一些代码,这些代码可以使用#something之类的字符串,然后将其转换为中间数据结构,以后可以利用它来执行与构造AST有关的更具体的任务。这个想法是,您希望将可能工作的最简单的东西包装到一个黑盒子中,该盒子允许您逐步和可靠地改进/更改/添加功能。首先不要尝试过度设计,而仅添加与当前手头任务相关的功能,以避免陷入分析瘫痪陷阱。

一旦在标记化步骤上做了一些迭代,就可以开始考虑下一个阶段,这是AST的Visitor / Walker的实现。我很自信地说您的设计会随着这个过程的发展而不断发展,因此,为变更而设计代码至关重要—这应将可测试性作为主要考虑因素。

尽管不是JavaScript,corresponding docker image and uploaded it to the dockerhub(完整披露:我是该回购协议的作者/维护者)非常接近地演示了您所要求的功能类型。 HTH