【发布时间】:2021-05-27 02:47:36
【问题描述】:
假设你有这种系统:
const input = [0, [1, 2, [3, 4, [8, 9], 6, 7], 4], [5, 6, 7], 3, 4, [8, 9], 6, 7, [1], 9]
const output = parse(input)
console.log(output.join('-'))
function parse(input) {
const output = []
iterate(input, value => {
check(() => isArray(value),
() => { // yes array
const children = parse(value)
output.push(...children)
},
() => { // not array
check(() => isEven(value), () => {
output.push(value)
})
})
})
return output
}
function isArray(value) {
return Array.isArray(value)
}
function isEven(value) {
return value % 2 == 0
}
function check(condition, success, failure) {
if (condition()) success()
else if (failure) failure()
}
function iterate(array, block) {
array.forEach(block)
}
本质上这就像一个树语法:
parse =
iterate input, value =>
check isArray(value)
call parse(value)
check isNumber(value)
check isEven(value)
push(value)
你可以把它想象成 JSON:
{
type: 'function',
name: 'parse',
children: [
{
type: 'iterate',
children: [
{
type: 'check',
checker: 'isArray',
children: [
{
type: 'call',
function: 'parse'
}
]
},
{
type: 'check',
checker: 'isNumber',
children: [
{
type: 'check',
checker: 'isEven',
children: [
{
type: 'push',
}
]
}
]
}
]
}
]
}
基本上我真正的问题是我在自定义编程语言中有类似 JSON 的东西,我想将它转换成一个状态 机器而不是像我们这样的嵌套/递归函数调用 从这篇文章开始。
所以我的问题是,如何重写本文开头的递归函数系统,使其使用状态机?
您不必一路走来,从 JSON(在这个例子中是不完整的,因为我没有一个好的 简化示例)。
相反,只要您能从本文开头展示如何将这个递归或嵌套函数系统重写为状态机,就够了。
我的想象是这样的:
let transitions = [
function1,
function2,
...
]
let transition = transitions[0] // the start function in theory
let currentInput = input
let someStack = []
while (transition) {
[currentInput, transition] = transition(someStack, currentInput)
}
但我很快就迷失了如何跟踪我们在输入中的位置,以及如何处理诸如迭代(如iterator)或“if 语句”(如check)。
function iterate(input) {
// you can't do the recursive call here,
// as the original while loop should handle this.
// but, we should return some reference to the current input,
// as well as the next transition.
}
如果必须选择一种语言,那么在 JavaScript 中执行此操作将是最简单的。但它甚至可以用伪代码来完成,以大致展示它是如何完成的。
【问题讨论】:
-
问题不清楚。 “解析”一词意味着输入是一个字符串,并且您逐个字符地读取。在您的示例中,
input不是已经解析的 JS 值。请澄清。 -
递归方法有什么问题?
-
@Olivier 通过解析我的意思是获取一些输入并将其转换为输出。我的示例使用嵌套数组系统(树),它接近我将“解析”的输入。但是,如果您可以更容易地想象一个字符串,那么任何一种方式都对我有用。递归方法不一定存在固有问题,我只是想知道如何以某种方式像过渡机器一样做到这一点。为了我的学习。
-
去功能化可能与您的问题相关:youtube.com/watch?v=wppzFzzD4b8
-
您好,您的赏金即将到期,如果您想要一个好的答案,您应该与 cmets 互动。 'isEven, isNumber isArray' 的集合是有限集吗?只有“isArray”才是“复合”?
标签: javascript algorithm parsing state-machine automata