首先,ts
的 github
地址:github.com/Microsoft/T… 。各位可先行下载。其编译部分位于 src/compiler
目录下。
其中分为以下几个关键部分,
- Scanner 扫描器(
scanner.ts
) - Parser 解析器(
parser.ts
) - Binder 绑定器(
binder.ts
) - Checker 检查器(
checker.ts
) - Emitter 发射器(
emitter.ts
)
每个部分在源文件中均有独立文件,稍后会解释这些部分在编译过程中所起到的左右。
概览
上图简单说明 TypeScript 编译器如何将上述几个关键部分组合在一起:
- 源码 ~ scanner(扫描器) ~ token数据流 ~ parser(解析器) -> AST(抽象语法树)
- AST(抽象语法树) ~ binder(绑定器) -> symbols(符号)
- AST(抽象语法树) + symbols ~ checker(检查器) -> 类型检查功能
- AST(抽象语法树) + checker(检查器) ~ emitter(发射器) -> js代码
流程 1: 源码 => AST
源码 ~ scanner(扫描器) ~ token数据流 ~ parser(解析器) -> AST(抽象语法树)
typescript的扫描器位于scanner.ts
,解析器位于parser.ts
,在内部,由 parser解析器
控制scanner扫描器
将源码
转化为抽象语法树(AST)
。流程如下:
若以常见的AST生成过程类比,可简单类比上述的 扫描器阶段
可对应为 词法分析过程
,解析器阶段
可对应为语法分析过程
。
有关AST抽象语法树
可参考 AST抽象语法树。
Parser 解析器对 Scanner 扫描器的使用
通过 parseSourceFile
设置初始状态并将工作交给 parseSourceFileWorker
函数。
parseSourceFile
export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor | undefined, setParentNodes = false, scriptKind?: ScriptKind): SourceFile {
scriptKind = ensureScriptKind(fileName, scriptKind);
//初始化状态
if (scriptKind === ScriptKind.JSON) {
const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes);
convertToObjectWorker(result, result.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
result.referencedFiles = emptyArray;
result.typeReferenceDirectives = emptyArray;