自著——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运算的准备 :得到词语的数组相关推荐

  1. 为什么《30天自制操作系统》封面中的猫是两只尾巴

    刚刚在一社区,发了一贴,被指出一问题,询一高人,得一答案.这便是我没有关注到的封面上的那只猫,我想这也是很多读者没有关注到的.因为在我微博的200转发贴中,并没有人提到封面中的猫为何有两只尾巴.于是咨 ...

  2. 发布在《30天自制操作系统》之前的帮助阅读贴

    说明:这是8月15日即将上市的一本新书,本文的摘选也可以命名为<30天自制操作系统>上市之前必读.本书幽默,有趣,可以说是技术书里的幽默书,让您读起来绝对不会感到乏味.在本书上市之前,您一 ...

  3. 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!

    <30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的 ...

  4. 写在《30天自制操作系统》上市之前

       这本<30天自制操作系统>马上就要在各大书店和网上商城全面上架了,作为本书的4位译者之一,我负责翻译了本书约三分之二的内容.这是我参与翻译的第一本译著,我感到很激动也很紧张,因为我知 ...

  5. 《30天自制操作系统》笔记(04)——显示器256色

    <30天自制操作系统>笔记(04)--显示器256色 进度回顾 从最开始的(01)篇到上一篇为止,已经解决了开发环境问题和OS项目的顶层设计问题. 本篇做一个小练习:设置显卡显示256色. ...

  6. 《30天自制操作系统》学习笔记--第好多天

    之前看<30天自制操作系统>,参考而成,和书中系统并不完全一致,是在原有基础上按照自己的习惯而成,由于水平和工作原因,未完成内存管理和文件系统,有兴趣者可以通过以下网址https://gi ...

  7. 由《30天自制操作系统》引发的漫画创作

    大家可还记得<30天自制操作系统>的封面上的那只猫吗?记得当时,在果壳网有人问,为何这只猫长了两只尾巴呢,延着这条线,我把这本书捧上了展示的舞台.事隔四个多月,我又重提此书. 这本经我手宣 ...

  8. 30天自制操作系统——第二十三天窗口操作

    窗口及输入切换 我们先来实现用键盘切换窗口,按下F11键,将最下面的窗口移动到最上面,这里F11按键的编码为0x57. bootpack.c节选: void HariMain(void) {(略)fo ...

  9. 30天自制操作系统-初体验

    最近在图书馆翻阅关于操作系统的书籍,看到川和秀实的自制操作系统决定也动手尝试一下,这本书书名就叫做30天自制操作系统.首先还是附上光盘镜像的获取地址吧.30天自制操作系统光盘镜像ISO完整版下载 - ...

最新文章

  1. html表格鼠标高亮行列,JS实现的表格行鼠标点击高亮效果代码
  2. block 实现原理详解(一)
  3. STL---string
  4. 关于.Net 1.1 Windows Forms 控件的一个小问题
  5. 矩阵可逆的一种刻画方式
  6. Bootstrap表单
  7. 如何自学python知乎-你是如何自学 Python 的?
  8. 查看-增强会话_会话助手平台-Hinglish Voice等!
  9. RFID EPC Class1 Gen2电子标签笔记
  10. 光敏传感器实验报告_光敏电阻的光敏特性研究实验报告.doc
  11. mappedBy的具体使用及其含义
  12. 字符串--------KMP算法(studying)
  13. 华为教父任正非的别样视野(转)
  14. 《变形金刚ONLINE》策划案
  15. 使用Julia运用JuMP和Clp求解Lp和ILP问题(分支定界法)
  16. 内蒙古联通云计算机,中国联通西北(呼和浩特)云计算基地
  17. 将计算机组织管理策略用于微信群管理
  18. 2022年山东省职业院校技能大赛“网络安全”比赛任务书
  19. 咖说 | TON 项目宣告终止!但社区还将继续进行开发和发币
  20. 无碳小车 matlab,基于无碳小车前轮运动关系的MATLAB运动轨迹仿真

热门文章

  1. 织梦(dede)各类实用标签代码
  2. MySQL基础(二)---MySQL服务基础与使用 MySQL 数据库
  3. CF817B Makes And The Product
  4. 电脑误删文件恢复怎么做?数据恢复,4招就行!
  5. Hbase—分布式数据库
  6. 从零写一个Asp.net core手脚架 (异常处理)
  7. 改进AnimeGANv2的图像动漫风格转换系统
  8. 计算机作文素材,雅思写作素材积累之计算机相关表达
  9. 差分进化算法和遗传算法的区别
  10. php在线考试系统4.0版本,网络在线考试系统4.0 多功能一体化考试平台 可二开!在线模拟考试系统商业版PHP源码...