【问题标题】:How can I force a user to indicate that they are switching from operator to operator如何强制用户表明他们正在从操作员切换到操作员
【发布时间】:2022-06-16 00:15:09
【问题描述】:

我正在创建一个用作“编程语言”的 JS 模块。这种编程语言可以解释人类的语言,并且应该将其翻译成 Javascript。

编程语言将严格遵守语法,类似于其他编程语言,这就是这里要完成的问题。

在我的编程语言中,您可以用多种不同的方式编写程序,但为了保持程序整洁,我喜欢将其分成块以提高可读性。此处显示的代码块:

...
add 2 and 2 
multiply by 5
...

会喷出来:

20

它是有效的,但如果我们也试图严格语法,我们将不得不问这个问题:

  1. 乘以 5?上一个数学方程式的结果,还是用户启动了另一个方程式?

如果我们使用前面数学方程的结果,代码需要看起来像这样:

...
add 2 and 2
then multiply the result by 5
...

仍然喷出相同的结果:

20

我怎样才能实现这个目标?

完整的源代码

source.js:

Array.prototype.remove = function(value) {
    for (var i = this.length; i--; )
    {
        if (this[i] === value) {
            this.splice(i, 1);
        }
    }
}

// from https://stackoverflow.com/questions/175739/how-can-i-check-if-a-string-is-a-valid-number
function isNumeric(str) {
  if (typeof str != "string") return false
  return !isNaN(str) && !isNaN(parseFloat(str))
}

function isOperand(token) {
  const ops = ["add", "multiply", "subtract", "divide"]
  if (ops.includes(token)) {
    return true
  }
  return false
}

function interpret(input) {
  const tokens = input.split(' ') // in fancy programming language terms, 
  // this is a lexical analysis step
  // note that we are not supporting things like
  // double spaces, something to think about!
  tokens.remove('\n')
  tokens.remove('')

  console.log(tokens)

  let state = 0 // we are keeping the results from our operation here

  for (i = 0; i < tokens.length; i++) {
    const t = tokens[i] // to keep things shorter
    if (!isOperand(t)) {
      throw new Error(`expected operand token, got: ${t}`)  
    }

    // all operators are binary, so these variables will hold the operands
    // they may be two numbers, or a number and the internal state
    let a, b;

    const next = tokens[i + 1]
    if (next == "by") {
      // we should add the next token (hopefully a number!) to the state
      a = state
      b = parseFloat(tokens[i + 2])
      i += 2 // very important! the two tokens we read should be skipped
      // by the loop. they were "consumed".
    } 
    else if (isNumeric(next)) {
      const and = tokens[i + 2] // this should be the "and"
      if (and != "and") {
          throw new Error(`expected "and" token, got: ${and}`)
      }
      a = parseFloat(next)
      b = parseFloat(tokens[i + 3])
      i += 3 // in this case, we are consuming more tokens 
    } else {
      throw new Error(`unexpected token: ${next}`)  
    }

    switch (t) {
      case "add": 
        state = a + b
        break;
      case "multiply":
        state = a * b
        break;
      case "subtract":
        state = a - b
        break;
      case "divide":
        state = a / b
        break;
    }
  }

  return state
}

function out(main) {
  console.log(interpret(main))
}

module.exports = {out}

index.js:

const cjs = require('./source.js')

var main =  `
  add 2 and 2 
  multiply by 5
`

cjs.out(main)

【问题讨论】:

  • 新运营商呢? result 获取当前状态,clear 重置当前状态(或类似的东西)?
  • 是的,我可能会这样做,但话又说回来,请记住,我们必须表明我们也在用 then 切换运算符,得到它是哪个,得到结果,然后乘以一个新数字。

标签: javascript programming-languages


【解决方案1】:

顺便说一句,您使用的操作数和操作符是错误的。操作数表示您执行操作的对象,在这种情况下是数字。运算符是操作定义符号(+、*等)

你应该定义另一种类型的操作符,比如'transitionOperator',它是由'then'关键字定义的

如果你遇到 transitionOperator (then) 你应该检查状态是否之前设置。如果它没有抛出错误,因为您无法从中转换。否则,您正在执行“then”转换操作,这意味着您需要使用先前操作的结果(您的状态变量)作为您的操作数 1,您的操作数 2 将是下一个标记。

例子:

add 2 and 2 // sets the state to 4
then multiply the result by 5 // operator1 = state, operator2 = 5, new state = 20

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多