【问题标题】:How to convert a string into a AST object with Javascript?如何使用 Javascript 将字符串转换为 AST 对象?
【发布时间】:2019-03-11 04:38:58
【问题描述】:

我需要将字符串转换为对象(类似于 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'
            }]
        }
    ]
};

【问题讨论】:

  • 虽然我确实发现这个问题引起了我的好奇心,但由于这个问题的解决方案的规模庞大,我认为它在当前状态下无法回答 - 你要求如何实现自定义 DSL 解释器/渲染器,这通常是很厚的教科书的主题! :) 您是否正在考虑一些我们可以帮助您决定的方法,或者更具体的方法?
  • 到目前为止,我已尝试以两种不同的方式解决此问题。 1)使用正则表达式,我发现自己陷入了困境。 2)使用基于Java但可以在javascript中生成访问者的工具ANTLR。我一直在寻找有关如何解决这个问题的想法,而不是具体的解决方案,即使最新的解决方案也会受到赞赏。 :)
  • 感谢您提供更多信息。希望我的回答能提供您正在寻找的那种指导!
  • OP 想要解析表达式。这并不像构建一个完整的 DSL 那样困难,也不需要复杂的机器。他应该查看我关于如何构建递归下降解析器的讨论,其中还讨论了如何构建 AST 作为解析过程的一部分。按照我的示例,他将能够很容易地用 JavaScript 编写代码。见stackoverflow.com/a/2336769/120163
  • 感谢您的链接,@Ira Baxter。 OP要求“关于如何解决这个问题而不是具体解决方案的想法”,如果您能详细说明“......构建完整的DSL”的意思,我将不胜感激 - 您是否认为表达式语法是一个DSL?

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


【解决方案1】:

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

这个问题的一大块将是你的表达式字符串的解析和随后的标记化。首先编写一些代码,这些代码可以采用#something 之类的字符串并将其转换为中间数据结构,以后可以利用该结构执行与构建 AST 相关的更具体的任务。这个想法是您希望将最简单的可能工作的东西包装到一个黑匣子中,使您能够以增量和可靠的方式改进/更改/添加功能。一开始尽量不要过度设计,只添加与当前手头任务相关的功能,以免陷入分析瘫痪陷阱。

在标记化步骤上完成一些迭代后,您就可以开始考虑下一阶段,即为您的 AST 实现访问者/步行者。我有信心说,您的设计会随着您完成此过程而发展,因此设计您的代码以进行更改至关重要——这应该包括可测试性作为主要考虑因素。

虽然它不是 javascript,但 this C#/Roslyn based project(完全披露:我是该存储库的作者/维护者)非常接近地展示了您所询问的功能类型。高温

【讨论】:

  • “中间数据结构”将在许多方面成为您的 DSL 的 HTML DOM 等价物。尝试在您最了解的工具和框架中寻找熟悉的模式,然后从中窃取想法和方法!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多