如何在不使用eval或构造函数的情况下在JavaScript中编写算术表达式解析器? [英] How do you write an arithmetic expression parser in JavaScript, without using eval or a constructor function?

查看:164
本文介绍了如何在不使用eval或构造函数的情况下在JavaScript中编写算术表达式解析器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个字符串:

 var str1 = "25*5+5*7";

不使用 eval 或构造函数JavaScript,我怎样才能编写一个名为output的函数,它接受字符串并输出字符串的算术值,在本例中为160?

Without using eval or the constructor function in JavaScript, how would I be able to write a function called "output" that takes in the string and outputs the arithmetic value of the string, which in this case is 160?

推荐答案

这是一个完整的优先级表达式求值程序,它遵循递归解析
的想法,我在OP的注释中链接到了问题。

Here's a full precedence expression evaluator following the recursive parsing idea I linked-to in a comment on the OP's question.

为此,首先我为我想要处理的表达式写了一个简单的BNF语法:

To do this, first I wrote a simple BNF grammar for the expressions I wanted to process:

sum =  product | sum "+" product | sum "-" product ;
product = term | product "*" term | product "/" term ;
term = "-" term | "(" sum ")" | number ;

这本身需要一些简单而直接的经验。如果您没有使用BNF的经验,您会发现
它非常适用于描述复杂的项目流,如表达式,消息,编程语言等...

This by itself requires a bit of experience to do simply and straightforwardly. If you have no experience with BNF you will find it incredibly useful for describing complex streams of items like expressions, messages, programming langauges, ...

使用那个语法,我按照其他消息
中概述的程序来生成以下代码。显而易见的是,它是以一种愚蠢的机械方式由语法驱动的,因此如果你有这种语法就很容易写。

Using that grammar, I followed the procedure outlined in the other message to produce the following code. It should be obvious that it is driven by grammar in a dumb mechanical way, and therefore pretty easy to write if you have that grammar.

(未经测试。我不是一个JavaScript编码器。这肯定会包含一些语法/语义问题。我花了大约15分钟来编写代码。)

(Untested. I'm not a JavaScript coder. This will surely contain a few syntax/semantic hiccups. Took me at about 15 minutes to code.)

var SE="Syntax Error";

function parse(str) { // returns integer expression result or SE
   var text=str;
   var scan=1;
   return parse_sum();

   function parse_sum() { 
      var number, number2;
      if (number=parse_product()==SE) return SE;
      while (true) {
        skip_blanks();
        if (match("+") {
           number2=parse_product();
           if (number2==SE) return SE;
           number+=number2;
        }
        else if (match('-')) {
                { number2=parse_product();
                  if (number2==SE) return SE;
                  number-=number2;
                } 
             else return number;
      }
   }

   function parse_product() {
      var number, number2;
      if (number=parse_number()==SE) return SE;
      while (true) {
        if (match("*") {
            number2=parse_term();
            if (number2==SE) return SE;
            number*=number2;
          }
          else if (match('/')) {
                  number2=parse_term();
                  if (number2==SE) return SE;
                  number/=number2;
               }
               else return number; 
      }
   }

   function parse_term() {
      var number;
      skip_blanks();
      if (match("(")) {
         number=parse_sum();
         if (number=SE) return SE;
         skip_blanks();
         if (!match(")") return SE;
      }
      else if match("-") {
              number= - parse_term();
           }
           else if (number=parse_number()==SE) return SE;
      return number;
   }

   function skip_blanks() {
      while (match(" ")) { };
      return;
    }

    function parse_number() {
       number=0;
       if (is_digit()) {
          while (is_digit()) {}
          return number;
        }
        else return SE;
    }

    var number;
    function is_digit() { // following 2 lines are likely wrong in detail but not intent
       if (text[scan]>="0" && text[scan]<="9") {
          number=number*10+text[scan].toInt();
          return true;
       }
       else return false;
    }

   function match(c) {
       if (text[scan]==c)
          { scan++; return true }
       else return false;
    }
 }

对此类解析器/评估器进行编码非常简单。请参阅关于如何构建解析器的我的答案(链接到如何构建评估程序)。

It is straightforward to code such parsers/evaluators. See my SO answer on how to build a parser (which links to how to how to build an evaluator).

这篇关于如何在不使用eval或构造函数的情况下在JavaScript中编写算术表达式解析器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆