【发布时间】:2022-06-16 00:15:09
【问题描述】:
我正在创建一个用作“编程语言”的 JS 模块。这种编程语言可以解释人类的语言,并且应该将其翻译成 Javascript。
编程语言将严格遵守语法,类似于其他编程语言,这就是这里要完成的问题。
在我的编程语言中,您可以用多种不同的方式编写程序,但为了保持程序整洁,我喜欢将其分成块以提高可读性。此处显示的代码块:
...
add 2 and 2
multiply by 5
...
会喷出来:
20
它是有效的,但如果我们也试图严格语法,我们将不得不问这个问题:
- 乘以 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