自制前端框架 Day.7 解析布尔值和null

先写个parse函数和parser类把现有代码包装一下

今天打算先把之前的代码整理一下,写一个parser类,包装一下Lexer,ASTBuilder,Compiler类。

function Parser(){
  var lexer = new Lexer();
  var astbilder = new ASTBuilder(lexer);
  this.compiler = new Compiler(astbilder);
}
Parser.prototype.parse = function(expression){
  return this.compiler.compile(expression);
}

function parse(expression){
  var parser = new Parser();
  return parser.parse(expression);
}

这样以后调用就方便了,写个测试案例试试:

describe('用parse函数编译',function(){
  it('编译整数',function() {
    var fn = parse('233')
    expect(fn()).toBe(233);
  })
})

思路

如果遇到的字符串不是数字也不是引号,而是一个字符,就进入解析identity流程,这个identity就是说在编程中我们遇到的一些已经定义好的值,比如true,false等等,这种值都是确定的,所以叫identify(确定).
先写一个函数判断是不是遇到了identify的值。

Lexer.prototype.isIdent=function(char){
  return ('a'<=char && char<='z')||('A'<=char&&char<='Z')||char==="_"||char==="$";
}

如果遇到这样的字符,就进入readIdent流程:

Lexer.prototype.lex=function(expression){
  this.tokens=[];
  this.text = expression;
  this.index = 0;
  while (this.index<this.text.length) {
    var currentChar = this.text.charAt(this.index);
    if(this.isNumber(currentChar)){
      this.readNumber();
    }else if (currentChar==="'"||currentChar==="\"") {
      this.readString(currentChar);
    }else if (this.isIdent(currentChar)) {
      this.readIdent()
    } else{
      throw "现在只支持数字,不支持别的字符"
    }
  }
  return this.tokens;
}

readIdent流程和其他的没什么不同,区别就是生成的token不一样,ident这种token没有值,因为值是已经被JS定义好的,只有text属性:

Lexer.prototype.readIdent = function () {
  var ident="";
  while(this.index<this.text.length){
    var currentChar = this.text.charAt(this.index);
    if(this.isIdent(currentChar)||this.isNumber(currentChar)){
      ident+=currentChar;
      this.index++;
    }
  }
  this.tokens.push({
    text:ident
  })
};

现在虽然有了一个token,但是在构建语法树的时候还是不行,因为构建语法树现在的body是tokens[0].value。显然这个token是没有value的。所以可以完善一下构建语法树的部分了:program的body属性现在是直接调用constant方法,完善一下,program调用一个新方法,primary方法。这个方法的意图是,所有节点的主处理方法。就是说处理其他节点都会通过这个方法过一次。
代码写好:

ASTBuilder.constants={
  'true':true,
  'false':false,
  'null':null
}
ASTBuilder.prototype.ast=function(expression){
  this.tokens = this.lexer.lex(expression);
  return this.program();
}
ASTBuilder.prototype.program=function(){
  return {
    type:ASTBuilder.Program,
    body:this.primary()
  }
}
ASTBuilder.prototype.primary=function(){
  if(ASTBuilder.constants.hasOwnProperty(this.tokens[0].text)){
    return {type:ASTBuilder.Literal,value:ASTBuilder.constants[this.tokens[0].text]}
  }else{
    return this.constant();
  }
}

先写个测试案例跑一下试试:

  it('编译true',function() {
    var fn = parse('true')
    expect(fn()).toBe(true);
  })
  it('编译false',function() {
    var fn = parse('false')
    expect(fn()).toBe(false);
  })
it('编译null',function() {
    var fn = parse('null')
    expect(fn()).toBe(null);
  })
编译null报错

编译null的时候出错了,跟一下看看怎么回事:

因为null就是啥都没有
image.png

这下明白了,因为现在生成的函数是这样:

function(){
  return ;
}
``
所以其实是什么都没返回,测试案例期待的null就不行。我应该让生成的函数是这样:

function(){
return null ;
}

这样只要修改一下escape方法就行了:

Compiler.prototype.escape=function(value){
if(webframe.isString(value)){
return "'"+
value.replace(this.stringEscapeReg,this.changeToUnicode)
+"'";
}else if (value===null) {
return 'null';
} else{
return value;
}
}

这就编译成功了:

![image.png](http://upload-images.jianshu.io/upload_images/839173-03ff761e4480264c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

今天已经开始写了这个东西第七天了,感觉进度还行,稳扎稳打,之前定的七个月,没准六个月就能完成呢。哈哈。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,719评论 0 33
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • 写到这儿的时候其实思路就有点乱了,很大部分的原因是之前的代码写了太久,有的地方确实忘了。所以今天打算趁机总结一下回...
    蚊子爸爸阅读 537评论 0 1
  • 中科院震惊调查:30年1000余高考状元下场悲惨来源 | 中国家庭教育摘要 调查结果:“恢复高考以来的1000名高...
    01公子阅读 196评论 0 1