Lexer & Parser
编译原理中,Lexer 和 Parser 结合在一起可以将代码转为 AST 抽象语法树,以进行后序AST转译,代码生成等步骤。本文章主要解析一下Lexer 和 Parser 的具体定义。
Lexer
在终结符 & 生产式 & 文法中,可以知道程序的最小组成单位是终结符,而Lexer就是将代码分割成终结符的程序
if (var1 > 0) {
let var1 = 1;
}
可以使用espree这个Javascript解析库来尝试获取下lexer的结果,
import * as espree from 'espree';
const code = `
if (var1 > 0) {
let var1 = 1;
}
`;
const options = {
ecmaVersion: 2022, // 使用最新的 ECMAScript 版本
sourceType: 'module', // 支持 ES 模块语法
comment: true, // 包含注释
tokens: true, // 生成词法标记
range: true, // 添加范围属性
loc: true // 添加行列位置信息
};
const tokens = espree.tokenize(code, options);
console.log(tokens);
运行后输出的Tokens包括Token的类型,内容还有在源码的位置信息,并且会发现输出的Tokens中,无意义字符(例如空格,换行符) 等被去掉,代表Lexer还有数据清洗的作用。
Token {
type: 'Keyword',
value: 'if',
start: 1,
end: 3,
loc: SourceLocation { start: [Position], end: [Position] },
range: [ 1, 3 ]
},
...
Parser
Parser是将Lexer的到Tokens,转为下面具有语法意义的AST抽象语法树的程序
同样可以使用espree体验输出的AST,或者可以使用astexplorer更直观地查看。
import * as espree from 'espree';
const code = `
if (var1 > 0) {
let var1 = 1;
}
`;
const options = {
ecmaVersion: 2022, // 使用最新的 ECMAScript 版本
sourceType: 'module', // 支持 ES 模块语法
comment: true, // 包含注释
tokens: true, // 生成词法标记
range: true, // 添加范围属性
loc: true // 添加行列位置信息
};
const ast = espree.parse(code, options);
console.log(ast);