自著——30天自制红孩儿解释器 第2天 A+B-C+D运算的准备 :得到词语的数组
自著——30天自制计算机语言解释器 第2天 A+B-C+D运算的准备 :得到词语的数组
根据第一天的开发,发现,程序解析时处理的最基础的单元
是词语(TOKEN),所以需要在做其它事情之前,先把整个表达式
拆分成多个词语,以方便之后的处理。
例如 1+2+3+4 处理成如下的数组
1 5 1 1 0 ----------
2 8 + 1 1 ----------
3 5 2 1 2 ----------
4 8 + 1 3 ----------
5 5 3 1 4 ----------
6 8 + 1 5 ----------
7 5 4 1 6 ----------
数组中的每个元素都是一个对象。有序号 类型 值 行号 行内起始位置 这五个属性组成。
例如如下:
id type value linenumber startIndex
1 keyword int 1 10
第2.1版本的程序
需求 针对 1+2+3+4 这样的表达式,检查语法错误。 例如操作数与操作数相连
或者是操作符与操作符 相连即为出错。
实现
循环遍历 词语的数组,判断相邻的词语 的类型是否一样,一样即为出错,并报出出错的位置。
词语 分成了九种类型
1 字符串型, 5数字型, 6分隔符型 7 块分隔符 8.操作符,9 空格符
BNF的定义如下:
<operand> :== + | - | * | / | = | < | > | % | ^ | & | | | !
<block> :== { | } | [ | ] | ( | )
<delimeter> :== , | ; | : | ' | "
<digit> :== 0 | 1|2|3|4|5|6|7|8|9
<number> :== <digit> | <digit> <number>|<digit> . <number>
a~Z letter keyword ,identifier ,variable
get_token函数实现的思路
采用类似于超级玛利的策略。
以 上跳,下跳 ,平跑 来分隔 词语。
off on 上跳 得到token 首字符
off off 平跑 过滤空格与分隔符
on on 平跑 得到token 其它字符
on off 下跳 token 结束
html页面代码如下
<HTML>
<HEAD>
<TITLE> 30天自制解释器 2.1 </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<script src='get_token_general.js' ></script>
</HEAD>
<BODY>
<p>本版本只能计算 a+b ,a-b,a*b ,a/b ,且本版有多个操作符,解析 操作数与操作数
操作符与操作符相连的错误 </p>
<p>a和b 都是正整数,而且 a 与 +,b 与+ 之间都可以有空格 </p>
<textarea id='txt1' rows="20" cols="80"></textarea>
<input type='button' value='执行' οnclick='eval()'>第二天第一版</input>
<textarea id='txt2' rows="20" cols="80"></textarea>
<script>
function eval()
{
var str=document.getElementById("txt1").innerText;
var result=0;
var token_array=[];
token_array=get_token_general({"lineno":1,"linelength":str.length,"str":str},token_array);
result=parse_exp(token_array);
if (temp.length>1)
{
if(temp[0]=='+')
{
result=addcalc(temp[1],temp[2]);}
else if (temp[0]=='-')
{result=subcalc(temp[2],temp[1]);}
else if(temp[0]=='*')
{
result=mulcalc(temp[1],temp[2]);}
else if (temp[0]=='/')
{result=divcalc(temp[2],temp[1]);}
}
else
{result=temp[0]+" can't eval"}
if (result==0)
result="parse success";
document.getElementById("txt2").innerText=result;
}
function parse_exp(arr)
{
var result=0;
var pretype=null;
for(var i=0;i<arr.length;i++)
{
if(pretype==null)
{pretype=arr[i].type;}
else if(pretype==arr[i].type)
{ result="error parse:at "+arr[i].startindex+" value: "+arr[i].value;}
else {pretype=arr[i].type}
}
return result;
}
function addcalc(operator1,operator2)
{
return parseInt(operator1)+parseInt(operator2);
}
function subcalc(operator1,operator2)
{
return parseInt(operator1)-parseInt(operator2);
}
function mulcalc(operator1,operator2)
{
return parseInt(operator1)*parseInt(operator2);
}
function divcalc(operator1,operator2)
{
var result =0;
if (operator2!=0)
{ result=parseInt(operator1)/parseInt(operator2);
}
else
{ result='runtime error : div is 0.'}
return result;
}
</script>
</BODY>
</HTML>
get_token_general.js 的代码如下:
//var b=[];
// a="int a,b;char c;c=a&&b;";
function get_token_general(a,b)
{
var str='';
var preState=0;
var curState=0;
var pretype=0;
var curtype=0;
var temp='';
var tempString='';
var id=b.length;
var startindex=0;
for(var i=0;i<a.linelength;i++)
{
str=a.str.substr(i,1);
curtype=getType(str);
curState=getState(preState,pretype,curtype);
temp=str;
if (curState==0) //(preState==0&&curState==0) // stop
{
id=id+1;
b.push({"id":id,"type":curtype,"value":temp,"lineno":a.lineno,"startindex":i});
}
else if (curState==1) //(preState==0&&curState==1) //jump up
{
startindex=i;
tempString=temp;
}
else if (curState==3) //(preState==1&&curState==0) //jump down
{
id=id+1;
b.push({"id":id,"type":pretype,"value":tempString,"lineno":a.lineno,"startindex":startindex});
id=id+1;
b.push({"id":id,"type":curtype,"value":temp,"lineno":a.lineno,"startindex":i});
tempString='';
}
else if (curState==8)
{
id=id+1;
b.push({"id":id,"type":pretype,"value":tempString,"lineno":a.lineno,"startindex":startindex});
tempString='';
}
else if (curState==2) //(preState==1&&curState==1) //run
{
tempString=tempString+temp;
}
else if (curState==4)
{
id=id+1;
b.push({"id":id,"type":pretype,"value":tempString,"lineno":a.lineno,"startindex":startindex});
startindex=i;
tempString=temp;
}
pretype=curtype;
preState=curState;
}
if(tempString!='')
{
id=id+1;
b.push({"id":id,"type":pretype,"value":tempString,"lineno":a.lineno,"startindex":startindex});
}
return b;
}
function getType(str)
{
var type=0;
if(isAlphabet(str)==1)
{
type=1;
}
else if(isDigit(str)==1)
{
type=5;
}
else if (isDelimiter(str)==1)
{
type=6;
}
else if (isBlock(str)==1)
{
type=7;
}
else if (isOperand(str)==1)
{
type=8;
}
else if ( isSpace(str)==1)
{
type=9;
}
return type;
}
function getState(preState,pretype,curtype)
{
var curState=0;
if(preState==0||preState==9||preState==3||preState==8)
{
if(curtype==5||curtype==1)
{curState=1;}
else if(curtype==6||curtype==7)
{ curState=0;}
else if(curtype==9)
{curState=9;}
}
else if(preState==1||preState==2)
{
if(curtype==5)
{
if(pretype!=8)
{curState=2;}
else
{curState=4;}
}
else if (curtype==1)
{
if(pretype==1)
{curState=2;}
else if (pretype==8)
{curState=4;}
else
{curState=2;}
}
else if(curtype==6||curtype==7)
{ curState=3;}
else if(curtype==8)
{curState=4;}
else if(curtype==9)
{curState=8;}
}
else if (preState==4)
{ if(curtype<=5&&pretype<=5)
{
curState=2;
}
else if(curtype==6||curtype==7)
{ curState=3;}
else if(curtype==8&&pretype==8)
{curState=2;}
else if(curtype==9)
{curState=8;}
else
{curState=4;}
}
else
{
curState=0;
}
return curState;
}
function isAlphabet(str)
{
var result=0;
if(str>='a' &&str<='z'||(str>='A'&&str<='Z'))
{
result=1;
}
return result;
}
function isDigit(str)
{
var result=0;
if(str>='0' &&str<='9'||(str=='.'))
{
result=1;
}
return result;
}
function isOperand(str)
{
var result=0;
if(str=='+')
{ result=1;}
else if (str=='-')
{ result=1;}
else if (str=='*')
{ result=1;}
else if (str=='/')
{ result=1;}
else if (str=='=')
{ result=1;}
else if (str=='>')
{ result=1;}
else if (str=='<')
{ result=1;}
else if (str=='%')
{ result=1;}
else if (str=='^')
{ result=1;}
else if (str=='&')
{ result=1;}
else if (str=='|')
{ result=1;}
return result;
}
function isDelimiter(str)
{
var result=0;
if(str==',')
{ result=1;}
else if (str==';')
{ result=1;}
else if (str==':')
{ result=1;}
return result;
}
function isBlock(str)
{
var result=0;
if(str=='(')
{ result=1;}
else if (str==')')
{ result=1;}
else if (str=='{')
{ result=1;}
else if (str=='}')
{ result=1;}
else if (str=='[')
{ result=1;}
else if (str==']')
{ result=1;}
return result;
}
function isSpace(str)
{
var result=0;
if(str==' ')
{ result=1;}
else if (str==' ')
{ result=1;}
return result;
}
自著——30天自制红孩儿解释器 第2天 A+B-C+D运算的准备 :得到词语的数组相关推荐
- 为什么《30天自制操作系统》封面中的猫是两只尾巴
刚刚在一社区,发了一贴,被指出一问题,询一高人,得一答案.这便是我没有关注到的封面上的那只猫,我想这也是很多读者没有关注到的.因为在我微博的200转发贴中,并没有人提到封面中的猫为何有两只尾巴.于是咨 ...
- 发布在《30天自制操作系统》之前的帮助阅读贴
说明:这是8月15日即将上市的一本新书,本文的摘选也可以命名为<30天自制操作系统>上市之前必读.本书幽默,有趣,可以说是技术书里的幽默书,让您读起来绝对不会感到乏味.在本书上市之前,您一 ...
- 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!
<30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的 ...
- 写在《30天自制操作系统》上市之前
这本<30天自制操作系统>马上就要在各大书店和网上商城全面上架了,作为本书的4位译者之一,我负责翻译了本书约三分之二的内容.这是我参与翻译的第一本译著,我感到很激动也很紧张,因为我知 ...
- 《30天自制操作系统》笔记(04)——显示器256色
<30天自制操作系统>笔记(04)--显示器256色 进度回顾 从最开始的(01)篇到上一篇为止,已经解决了开发环境问题和OS项目的顶层设计问题. 本篇做一个小练习:设置显卡显示256色. ...
- 《30天自制操作系统》学习笔记--第好多天
之前看<30天自制操作系统>,参考而成,和书中系统并不完全一致,是在原有基础上按照自己的习惯而成,由于水平和工作原因,未完成内存管理和文件系统,有兴趣者可以通过以下网址https://gi ...
- 由《30天自制操作系统》引发的漫画创作
大家可还记得<30天自制操作系统>的封面上的那只猫吗?记得当时,在果壳网有人问,为何这只猫长了两只尾巴呢,延着这条线,我把这本书捧上了展示的舞台.事隔四个多月,我又重提此书. 这本经我手宣 ...
- 30天自制操作系统——第二十三天窗口操作
窗口及输入切换 我们先来实现用键盘切换窗口,按下F11键,将最下面的窗口移动到最上面,这里F11按键的编码为0x57. bootpack.c节选: void HariMain(void) {(略)fo ...
- 30天自制操作系统-初体验
最近在图书馆翻阅关于操作系统的书籍,看到川和秀实的自制操作系统决定也动手尝试一下,这本书书名就叫做30天自制操作系统.首先还是附上光盘镜像的获取地址吧.30天自制操作系统光盘镜像ISO完整版下载 - ...
最新文章
- html表格鼠标高亮行列,JS实现的表格行鼠标点击高亮效果代码
- block 实现原理详解(一)
- STL---string
- 关于.Net 1.1 Windows Forms 控件的一个小问题
- 矩阵可逆的一种刻画方式
- Bootstrap表单
- 如何自学python知乎-你是如何自学 Python 的?
- 查看-增强会话_会话助手平台-Hinglish Voice等!
- RFID EPC Class1 Gen2电子标签笔记
- 光敏传感器实验报告_光敏电阻的光敏特性研究实验报告.doc
- mappedBy的具体使用及其含义
- 字符串--------KMP算法(studying)
- 华为教父任正非的别样视野(转)
- 《变形金刚ONLINE》策划案
- 使用Julia运用JuMP和Clp求解Lp和ILP问题(分支定界法)
- 内蒙古联通云计算机,中国联通西北(呼和浩特)云计算基地
- 将计算机组织管理策略用于微信群管理
- 2022年山东省职业院校技能大赛“网络安全”比赛任务书
- 咖说 | TON 项目宣告终止!但社区还将继续进行开发和发币
- 无碳小车 matlab,基于无碳小车前轮运动关系的MATLAB运动轨迹仿真
热门文章
- 织梦(dede)各类实用标签代码
- MySQL基础(二)---MySQL服务基础与使用 MySQL 数据库
- CF817B Makes And The Product
- 电脑误删文件恢复怎么做?数据恢复,4招就行!
- Hbase—分布式数据库
- 从零写一个Asp.net core手脚架 (异常处理)
- 改进AnimeGANv2的图像动漫风格转换系统
- 计算机作文素材,雅思写作素材积累之计算机相关表达
- 差分进化算法和遗传算法的区别
- php在线考试系统4.0版本,网络在线考试系统4.0 多功能一体化考试平台 可二开!在线模拟考试系统商业版PHP源码...