ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

自著——30天自制红孩儿解释器 第14天 执行IF和WHILE 语句(1)简单情况

2021-09-21 21:33:16  阅读:93  来源: 互联网

标签:arr 30 14 res 自著 else var result operator2


自著——30天自制红孩儿解释器   第14天 执行IF和WHILE 语句(1)简单情况

在第13天对IF进行了解析,今天开始对IF条件语句
执行,首先对BNF进行修改。

<if statement> :== IF <if statement body>
|  IF <if statement bo`y>  ELSE <else body>
|  IF <if statement body>  [else if <if statement body> ]*  
|  IF <if statement body>  [else if <if statement body> ]*  ELSE <else body>

修改成
<if statement> :== <if statment section> ( null | <else statement section>
| <else if statement section> |  <else if statement section> <else statement section>   )
<if statment section>       :== IF <if statement body>
<else if statement section> :==  else if <if statement body> <else if statement section>
<else statement section>    :==  ELSE <else body>

以上的修改,为第14.1版本的程序。

第14天第二版本程序
a=1; if(a>1) {b=2;}

第14天第三版本程序
a=1;while (a<10) {a=a+1;}

增加WHILE 循环语句的BNF定义。
 <while statment>    :== WHILE <while statement body>
 <while statement body> :== ( <logic expression>  )  <while body>
 <while body> :==  { <statement list> }
 
<HTML>
<HEAD>
<TITLE> 30天自制解释器 14.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>
<script src='execute_lib.js' ></script>
<script src='symbol_table_operation.js' ></script>
</HEAD>
<BODY>
<p></p>
<p></p>
<p> aget_token_general=5;
b=a+1;
a
</p>
<p> </p>
<p>解析IF 语句 ,本版本与13.4 功能相同。程序重构。</p>
<p>if (a>1) {b=2;} else if (a==1) {c=2;}</p>
<textarea id='txt1' rows="20" cols="80"></textarea>
<input type='button' value='翻译成lisp程序' οnclick='eval()'>第十四天第一版</input>
<input type='button' value='执行' οnclick='execute()'>execute</input>
<textarea id='txt2' rows="20" cols="80"></textarea>
<p>error show area:</p>
<textarea id='txt3' rows="20" cols="80"></textarea>
<script>
function eval()
{
var str=document.getElementById("txt1").innerText;
var result=0;
var token_array=[];
var result_str="";
  token_array=get_token_general({"lineno":1,"linelength":str.length,"str":str},token_array);

  // result=parse_sim_exp(token_array,0,0);
  //   result=parse_relation_exp(token_array,0,0);
     //   result=parse_logic_exp(token_array,0,0);
    result= parse_compound_statement(token_array,0,0);
    // result=test_symboltable_operation(token_array);
  // if (hasError(result.res)==0)
      // result=execute_exp(token_array);
    // result_str=sysmbol_table_arrtostring(result);
document.getElementById("txt2").innerText=result.res;//result_str;  //
}

function execute()
{
var str=document.getElementById("txt1").innerText;
var result={};
var token_array=[];
var result_str="";
  token_array=get_token_general({"lineno":1,"linelength":str.length,"str":str},token_array);
    //result= execute_assign_statement(token_array,0,0,[]);
    result= execute_assign_compound_statement(token_array,0,0,[]);
    result_str=sysmbol_table_arrtostring(result.symbol_table);
document.getElementById("txt2").innerText=result_str; //result.res;//
}

function test_symboltable_operation(token_arr)
{
var symbol_table_arr=[];
   for (var i=0;i<token_arr.length;i++)
   {
       if (isVariable(token_arr[i])==1)
       {symbol_table_arr=symbol_table_do_variable(symbol_table_arr,token_arr[i].value,token_arr[i]);}
   }
   return symbol_table_arr;
}


fujction  parse_compound_statement(arr,i,level)
{
  var result="";
  var resultstr="";
  while(i<arr.length-1&&arr[i].value!='}')
    {
       if(arr[i].value==';')
         {i+=1;}
         if (isVariable(arr[i])==1) {
              result=parse_assign_statement(arr,i,level);
                i=result.i;
                resultstr=resultstr+" "+result.res;
           }
         else if (arr[i].value=='if')
          {
             result=parse_if_statement(arr,i,level+1);
               i=result.i;
               resultstr=resultstr+" "+result.res;
          }
    
       if(i<arr.length-1&&arr[i+1].value==';')
         {i+=1;}
       else
          {break;}
    }
     return {"res":resultstr,"i":i-1};
}

function parse_if_statement(arr,i,level)
{
  var result="";  
   var operator2={};
   var operator3={};
 
            operator2=parse_if_statement_section(arr,i,level);
             if( hasError(operator2.res)==-1)
                {
                  if (operator2.i<arr.length-2&&arr[operator2.i+1].value=='else' && (arr[operator2.i+2].value!='if'))
                     {
                        operator3=parse_else_statement_section(arr,operator2.i+1,level);
                        if( hasError(operator3.res)==-1)
                          {i=operator3.i;
                          // result= operator2.res+" "+operator3.res;
                       result=make_lisp_program_action("if",operator2.res,operator3.res);
                          }
                         else if(hasError(operator3.res)>=0)
                               {result=operator3.res;            
                               }
                     }
                  else if (operator2.i<arr.length-2&&arr[operator2.i+1].value=='else' && (arr[operator2.i+2].value=='if'))
                     {
                          operator3=parse_else_if_statement_section(arr,operator2.i+1,level);    
                            if( hasError(operator3.res)==-1)
                          {i=operator3.i;
                           result= "("+operator3.res+")";
                          
                           if (i<arr.length-2&&arr[i+1].value=='else')
                           {
                                   operator3=parse_else_statement_section(arr,i+1,level);
                            if( hasError(operator3.res)==-1)
                              {i=operator3.i;
                                  result= result+" ("+operator3.res+")";
                                
                              }
                             else if(hasError(operator3.res)>=0)
                               {result=operator3.res;            
                               }
                           }
                            result=make_lisp_program_action("cond",operator2.res, result);
                          }
                         else if(hasError(operator3.res)>=0)
                               {result=operator3.res;            
                               }
                     }
                  else {
                       result=make_lisp_program_action("if",operator2.res,"");
                       i=operator2.i;
                     }
                }
             else if(hasError(operator2.res)>=0)
                {result=operator2.res;            
                }
   return   {"res":result,"i":i};
}

function parse_if_statement_section(arr,i,level)
{
     var result="";  
   var operator2={};
   if (i<arr.length-2&&arr[i].value=='if')
          {
            i=i+1;
            operator2=parse_if_statement_body(arr,i,level);
                if( hasError(operator2.res)==-1)
                {
                  result=operator2.res;
                  i=operator2.i;
                }
                  else if(hasError(operator2.res)>=0)
                {result=operator2.res;            
                }
          }
    else {
        result='[error]: is not a keyword if: at '+arr[i].startindex+" value: "+arr[i].value;;
     }

   return   {"res":result,"i":i};
}
function parse_else_if_statement_section(arr,i,level)
{
       var operator2={};
        var operator3={};
        var result="";  
        if (i<arr.length-2&&arr[i].value=='else' && (arr[i+1].value=='if'))
                     {
                       operator2=parse_if_statement_body(arr,i+2,level);
                      if( hasError(operator2.res)==-1)
                        {
                            result=operator2.res;
                            i=operator2.i;
                            operator3=parse_else_if_statement_section(arr,i+1,level);
                             if( hasError(operator3.res)==-1)
                             {i=operator3.i;
                               result= operator2.res+" "+operator3.res;
                         //  result=make_lisp_program_action("if",operator2.res,operator3.res);
                              }
                             else if(hasError(operator3.res)>=0)
                               {result=operator3.res;            
                               }
                         }
                     else if(hasError(operator2.res)>=0)
                         {result=operator2.res;            
                         }
                     }
         else {i=i-1;}
    return   {"res":result,"i":i};
}

function parse_else_statement_section(arr,i,level)
{       var operator3={};
        var result="";  
        if (i<arr.length-2&&arr[i].value=='else' && (arr[i+1].value!='if'))
                     {
                         operator3=parse_else_body(arr,i+1,level);
                        if( hasError(operator3.res)==-1)
                          {i=operator3.i;
                           result= operator3.res;
                         //  result=make_lisp_program_action("if",operator2.res,operator3.res);
                          }
                         else if(hasError(operator3.res)>=0)
                               {result=operator3.res;            
                               }
                     }
    return   {"res":result,"i":i};
}

function parse_if_statement_body(arr,i,level)
{
  var result="";  
   var operator2={};
   var operator3={};
   if (arr[i].value=='(')
          {
            i=i+1;
            operator2=parse_logic_exp(arr,i,level);
             if( hasError(operator2.res)==-1)
                {
                  //result=make_lisp_program_action(arr[i+1].value,result,operator2.res);
                  i=operator2.i+1;
                  if(arr[i].value==')'){
                     operator3=parse_else_body(arr,i+1,level);
                        if( hasError(operator3.res)==-1)
                          {i=operator3.i;
                           result= operator2.res+" "+operator3.res;
                          }
                         else if(hasError(operator3.res)>=0)
                               {result=operator3.res;            
                               }
                  }
                  else {
                      result='[error]: is not a block ): at '+arr[i].startindex+" value: "+arr[i].value;
                  }
                }
             else if(hasError(operator2.res)>=0)
                {result=operator2.res;            
                }
          }
    else {
        result='[error]: is not a block (: at '+arr[i].startindex+" value: "+arr[i].value;
     }

   return   {"res":result,"i":i};
}
function parse_else_body(arr,i,level)
{
     var result="";  
   var operator2={};
   var operator3={};
   if (arr[i].value=='{')
          {
            i=i+1;
            operator2=parse_compound_statement(arr,i,level);
             if( hasError(operator2.res)==-1)
                {
                  //result=make_lisp_program_action(arr[i+1].value,result,operator2.res);
                  i=operator2.i+1;
                  if(i<arr.length&&arr[i].value=='}'){
                  result= operator2.res;
                  }
                  else {
                      result='[error]: is not a block }: at '+arr[i].startindex+" value: "+arr[i].value;
                  }
                }
             else if(hasError(operator2.res)>=0)
                {result=operator2.res;            
                }
          }
    else {
        result='[error]: is not a block {: at '+arr[i].startindex+" value: "+arr[i].value;
     }

   return   {"res":result,"i":i};
}

function parse_assign_statement(arr,i,level)
{
      var operator1={};
   var operator2={};
   var result="";  

        operator1=  parse_variable(arr,i,level);
        if(hasError(operator1.res)>=0)
              {
                 return {"res":operator1.res,"i":i};
              }
              else {result =operator1.res;
              i=operator1.i;
              }

   if (  i<arr.length-2 &&(arr[i+1].value=='=') )
     {
        operator2= parse_logic_exp(arr,i+2,level);
         if( hasError(operator2.res)==-1)
           {
         result=make_lisp_program_action(arr[i+1].value,result,operator2.res);
       //result=execute_binary_relation_operator_action(arr[i+1].value,result,operator2.res);
           i=operator2.i;
           }
         else if(hasError(operator2.res)>=0)
              {result=operator2.res;
             //  break;
              }
            
     }
    return {"res":result,"i":i};
}

function parse_variable(arr,i,level)
{
  var result=0;
 // var resultObj={};

   if(isVariable(arr[i])==1)
     {result=arr[i].value;}   
     else
       {result='[error]: is not a vairable: at '+arr[i].startindex+" value: "+arr[i].value;}
    return {"res":result,"i":i};
}
function parse_logic_exp(arr,i,level)
{
   var operator1={};
   var operator2={};
   var result="";  

        operator1=  parse_relation_exp(arr,i,level);
        if(hasError(operator1.res)>=0)
              {
                 return {"res":operator1.res,"i":i};
              }
              else {result =operator1.res;
              i=operator1.i;
              }

   while(  i<arr.length-2 &&(arr[i+1].value=='&&'||arr[i+1].value=='||' || arr[i+1].value=='^^') )
     {
        operator2= parse_relation_exp(arr,i+2,level);
         if( hasError(operator2.res)==-1)
           {
         //result=execute_binary_logic_operator_action(arr[i+1].value,result,operator2.res);
           result=make_lisp_program_action(arr[i+1].value,result,operator2.res);
           i=operator2.i;
           }
         else if(hasError(operator2.res)>=0)
              {result=operator2.res;
               break;
              }
            
     }
    return {"res":result,"i":i};
}


function parse_relation_exp(arr,i,level)
{
       var operator1={};
   var operator2={};
   var result="";  

        operator1=  parse_sim_exp(arr,i,level);
        if(hasError(operator1.res)>=0)
              {
                 return {"res":operator1.res,"i":i};
              }
              else {result =operator1.res;
              i=operator1.i;
              }

   if (  i<arr.length-2 &&(arr[i+1].value=='>'||arr[i+1].value=='<'||arr[i+1].value=='>='||arr[i+1].value=='<='||arr[i+1].value=='=='||arr[i+1].value=='<>') )
     {
        operator2= parse_sim_exp(arr,i+2,level);
         if( hasError(operator2.res)==-1)
           {
         //result=execute_binary_relation_operator_action(arr[i+1].value,result,operator2.res);
          result=make_lisp_program_action(arr[i+1].value,result,operator2.res);
           i=operator2.i;
           }
         else if(hasError(operator2.res)>=0)
              {result=operator2.res;
             //  break;
              }
            
     }
    return {"res":result,"i":i};
}

function parse_sim_exp(arr,i,level)
{
   var operator1={};
   var operator2={};
   var result="";  

        operator1=  parse_term(arr,i,level);
        if(hasError(operator1.res)>=0)
              {
                 return {"res":operator1.res,"i":i};
              }
              else {result =operator1.res;
              i=operator1.i;
              }

   while(  i<arr.length-2 &&(arr[i+1].value=='+'||arr[i+1].value=='-') )
     {
        operator2= parse_term(arr,i+2,level);
         if( hasError(operator2.res)==-1)
           {
    //     result=execute_binary_calc_operator_action(arr[i+1].value,result,operator2.res);
     result=make_lisp_program_action(arr[i+1].value,result,operator2.res);
           i=operator2.i;
           }
         else if(hasError(operator2.res)>=0)
              {result=operator2.res;
               break;
              }
            
     }
    return {"res":result,"i":i};
}

function parse_term(arr,i,level)
{
   var operator1=0;
   var operator2=0;
   var result="";
        operator1=  parse_factor(arr,i,level);
        if(hasError(operator1.res)>=0)
              {
               return {"res":operator1.res,"i":i};
              }
              else {result =operator1.res;
               i=operator1.i;}

   while( i<arr.length-2 &&(arr[i+1].value=='*'||arr[i+1].value=='/')  )
     {
        operator2= parse_factor(arr,i+2,level);

         if( hasError(operator2.res)==-1)
           {
          // result=execute_binary_calc_operator_action(arr[i+1].value,result,operator2.res);
           result=make_lisp_program_action(arr[i+1].value,result,operator2.res);
            i=operator2.i;
           }
         else if(hasError(operator2.res)>=0)
              {result=operator2.res;
               break;
              }

     }

    return {"res":result,"i":i};
}

function parse_factor(arr,i,level)
{
  var result=0;
  var resultObj={};

   if(isNum(arr[i].value)==1)
     {result=arr[i].value;}
    else if (arr[i].type==7)
      {
         if (arr[i].value=='(')
         {
                 resultObj=parse_sim_exp(arr,i+1,level+1);
                 result=resultObj.res;
                 i=resultObj.i;
         }

          if (i<arr.length-1&& arr[i+1].value==')')
          {
                 i=i+1;
          }
          else if (i==arr.length-1 && arr[i]!=')')
              {
                   result='[error]: should be  ) : at '+arr[i].startindex+" but value: "+arr[i].value;
              }
          else
          {
              result='[error]: should be  ) : at '+arr[i].startindex+" but value: "+arr[i].value;
          }
      }
     else if (isVariable(arr[i])==1)
        {
           result= arr[i].value;
        }
     else
       {result='[error]: is not number: at '+arr[i].startindex+" value: "+arr[i].value;}
    return {"res":result,"i":i};
}

function hasError(str)
{
 if(isNum(str)==1)
    return -1;
  else
  return str.indexOf("error");
}

function make_lisp_program_action(operand,operator1,operator2)
{
   return "("+ operand + " "+operator1+" "+operator2+")";
}

</script>
</BODY>
</HTML>

标签:arr,30,14,res,自著,else,var,result,operator2
来源: https://blog.csdn.net/gggwfn1982/article/details/120405685

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有