支持If语句- 一步步实现JS语言编译执行
上几节中,还都是对语句的解析执行, 本节加入if语句
的支持,同时引入二义性的概念
目标
支持If语句
了解If语句
一般我们的if语句是这样的
if(a >2) {
a = 3;
}else {
a=4;
}
if关键字
+ 判断表达式
+ 语句块
对应的文法:
if ( Expression ) Statement else Statement (文法语句1)
if ( Expression ) Statement (文法语句2)
我们来看下下面几个if语句
if(a >2)
if(a<4)
a=3;
else
a=4;
该语句解析成ast应该是什么样的?
- 解法一
- 解法二
文法二义性, 即只我们根据这个文法可以得到两颗不同的语法树。 如果我们先匹配文法语句2, 即上面的解法一、二
高级语言中通常都是else和最近的一个if匹配, 我们的实现也将基于此!
如何实现
前置条件
- if语句块有个test部分,返回一个boolean类型的值, 所以我们至少需要支持关系表达式的计算了(这部分和前几节一致,不展开)
- if 和 else本身会更一个代码块
block
, 所以语句块的解析需要支持
/**
* v0.0.4
*
* 代码块 以{开始, 以}结束
* Block :
* { StatementList(opt) }
*
*/
block() {
let node = null;
let nextToken = this.lexerLevel.tokenPeek()
if(nextToken && nextToken.type === this.lexerLevel.DfaState.LeftBrace) {
node = new BlockAstNode("Block", "")
this.lexerLevel.tokenRead();
nextToken = this.lexerLevel.tokenPeek()
// todo 异常判断
while(nextToken && nextToken.type !== this.lexerLevel.DfaState.RightBrace){
let child = this.statement();
if(child) {
// 构建子级ast
node.addChild(child)
}
nextToken = this.lexerLevel.tokenPeek()
}
if(nextToken && nextToken.type === this.lexerLevel.DfaState.RightBrace) {
this.lexerLevel.tokenRead();
}
}
return node
}
实现if语句
/**
* v0.0.4
*
* 语法如下
* IfStatement :
* if ( Expression ) Statement else Statement
* if ( Expression ) Statement
*
*/
ifStatement() {
let node = null;
let nextToken = this.lexerLevel.tokenPeek()
// 预判进入If语句
if(nextToken && nextToken.type === this.lexerLevel.DfaState.If) {
this.lexerLevel.tokenRead();
// 构建一个if Ast
node = new IfStatementAstNode('ifStatement', 'if')
nextToken = this.lexerLevel.tokenPeek()
if(nextToken && nextToken.type === this.lexerLevel.DfaState.LeftParen) {
this.lexerLevel.tokenRead();
// test语句检查 TODO 暂时使用该 Expression
let childTest = this.relational();
if(childTest) {
node.addTest(childTest)
// 判断 )
nextToken = this.lexerLevel.tokenPeek()
if(nextToken && nextToken.type === this.lexerLevel.DfaState.RightParen) {
this.lexerLevel.tokenRead();
// 开始进入 statement区域判断
let child1 = this.statement();
if(child1) {
node.addConsequent(child1)
}else {
throw Error("lost consequent block in if statement")
}
// 判断else语句
nextToken = this.lexerLevel.tokenPeek()
if(nextToken && nextToken.type === this.lexerLevel.DfaState.Else) {
this.lexerLevel.tokenRead();
// 构建一个else代码块
let child2 = this.statement();
if(child2) {
node.addAlternate(child2)
}else {
throw Error("lost alternate block in if statement")
}
}
} else {
throw Error("lost rightParen in if test")
}
} else {
throw Error("lost test expression in if statement")
}
} else {
throw Error("lost leftParen in if test")
}
}
return node;
}
执行计算
if语句的计算比较简单, 我们只需要对语句块的test部分判断Boolean值,true则走if块, false走else块即可
getValue(){
// console.log("=====if value", this.test.getValue())
let testVal = !!(this.test.getValue()) // 转换成boolean
if(testVal) {
return this.consequent.getValue();
} else if(this.alternate) {
return this.alternate.getValue();
}
}
测试
- 简单if语句
let syntaxLevel = new SyntaxLevel1(`
if(a >2) {
a = 3;
}
`)
console.log("test1----", syntaxLevel.astParse())
结果:
AstNode {
type: 'Program',
value: '',
children:
[ IfStatementAstNode {
type: 'ifStatement',
value: 'if',
children: [Array],
parent: [Circular],
test: [BinaryAstNode],
consequent: [BlockAstNode],
alternate: null } ],
parent: null }
- 测试if else
let syntaxLevel2 = new SyntaxLevel1(`
if(a >2) {
a = 3;
}else {
a=4;
}
`)
console.log("test2----", syntaxLevel2.astParse())
结果:
AstNode {
type: 'Program',
value: '',
children:
[ IfStatementAstNode {
type: 'ifStatement',
value: 'if',
children: [Array],
parent: [Circular],
test: [BinaryAstNode],
consequent: [BlockAstNode],
alternate: [BlockAstNode] } ],
parent: null }
- 测试上述有二义性的语句
let syntaxLevel3 = new SyntaxLevel1(`
if(a >2)
if(a<4)
a=3;
else
a=4;
`)
console.log("test3----", syntaxLevel3.astParse())
结果:
AstNode {
type: 'Program',
value: '',
children:
[ IfStatementAstNode {
type: 'ifStatement',
value: 'if',
children: [Array],
parent: [Circular],
test: [BinaryAstNode],
consequent: [IfStatementAstNode],
alternate: null } ],
parent: null }
- 测试运算
// 测试运行计算
let syntaxLevel4 = new SyntaxLevel1(`
var a = 5;
if(a >2)
if(a<4)
a=3;
else
a=4;
a= a+1;
`)
console.log("test4----", syntaxLevel4.exe())
结果
5
标题:支持If语句- 一步步实现JS语言编译执行
作者:hugh0524
地址:https://blog.uproject.cn/articles/2020/02/27/1582816225074.html
0 0