如何获取TypeScript的语法树?

24

如何获取编译器的语法树?我们被分配了一个需要访问TypeScript语法树的项目(它是开源的,因此我们可以看到整个编译器的代码)。但是我们不知道如何获取它。我已经在互联网上阅读了一些文章,但我无法找到一个用户友好或用通俗易懂的语言写的文章。我相信有些人提到了我们需要做的第一步是找到解析步骤。但是在那之后我们不知道该怎么办。

抱歉问这种初学者问题 :)


1
除非有人已经深入研究过这段代码,否则对你来说帮助不大。你正在学习的是,在一个庞大的软件中,很难找到自己的方向。你需要花时间挖掘源代码。一个明显的技巧是在源代码中搜索单词"parse"、"tree"和"node";定义/构建AST的代码肯定在其中之一附近,除非代码库真的很糟糕。许多程序员喜欢使用的标准工具是"grep"。如果你不知道它是什么,请在维基百科上查找。 - Ira Baxter
1
这个后续问题上的答案可能会有用... TypeScript: 获取语法树 - Fenton
1
从大多数编译器获取AST的问题很困难;更糟糕的是,它们所拥有的AST往往是特有的。你可能考虑另一个选择,找到一个解析器生成器,或者更好地,一个程序转换,并使用(开发)TypeScript的语法;这样的工具通常很容易构建一个可用于非编译目的的AST。 - Ira Baxter
2个回答

16

TypeScript编译器API非常易于使用。要解析TypeScript文件并获取AST,请尝试以下操作:

const ts = require('typescript');
const sourceFile = ts.createSourceFile(filename,
    fs.readFileSync(filename).toString(), ts.ScriptTarget.ES6, false);
console.log(sourceFile.ast);

这将生成抽象语法树,例如:

{
  "kind": 251,
  "pos": 0,
  "end": 1097,
  "flags": 0,
  "bindDiagnostics": [],
  "languageVersion": 2,
  "fileName": "slidingWindow.ts",
  "languageVariant": 0,
  "scriptKind": 3,
  "referencedFiles": [],
  "amdDependencies": [],
  "statements": [
    {
      "kind": 218,
      "pos": 0,
      "end": 69,
      "flags": 0,
      "name": {
        "kind": 69,
        "pos": 10,
        "end": 22,
        "flags": 0,
        "text": "Accumulator",
        "kindDecoded": "Identifier"
      },
      "members": [
        {
          "kind": 148,
          "pos": 24,
          "end": 67,
          "flags": 0,
          "parameters": [
            {
              "kind": 139,
              "pos": 28,
              "end": 42,
              "flags": 0,
              "name": {
                "kind": 69,
                "pos": 28,
                "end": 32,
                "flags": 0,
                "text": "data",
                "kindDecoded": "Identifier"
              },
              "type": {
                "kind": 157,
                "pos": 33,
                "end": 42,
                "flags": 0,
                "elementType": {
                  "kind": 128,
                  "pos": 33,
                  "end": 40,
                  "flags": 0,
                  "kindDecoded": "NumberKeyword"
                },
                "kindDecoded": "ArrayType"
              },
              "kindDecoded": "Parameter"
            },
            {
              "kind": 139,
              "pos": 43,
              "end": 57,
              "flags": 0,
              "name": {
                "kind": 69,
                "pos": 43,
                "end": 49,
                "flags": 0,
                "text": "index",
                "kindDecoded": "Identifier"
              },
              "type": {
                "kind": 128,
                "pos": 50,
                "end": 57,
                "flags": 0,
                "kindDecoded": "NumberKeyword"
              },
              "kindDecoded": "Parameter"
            }
          ],
          "type": {
            "kind": 128,
            "pos": 59,
            "end": 66,
            "flags": 0,
            "kindDecoded": "NumberKeyword"
          },
          "kindDecoded": "CallSignature"
        }
      ],
      "kindDecoded": "InterfaceDeclaration"
    },
...

1

你需要从特定编译器中获取AST,还是只需要从TypeScript程序中获取语法树?如果你关心后者,那么你可能需要获取TypeScript的BNF语法(起点在这里),然后使用ANTLR等工具。它有一个名为ANTLRWorks的工具,可以让你可视化程序的语法树。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接