# 如何使用非递归堆栈编写递归函数？How do you write a recursive function using a non-recursive stack?

• `grammar`有很多表达方式
• `expression`有很多`matchers`
• `matcher`有许多`tokens` （或者其他任何更好的词）
• `token`可以指向另一个`expression` ，也可以是原始字符串或正则表达式。 因此，如果它指向另一个表达式，则这是递归开始的位置。

``````var grammar = new Grammar('math');
var expression = grammar.expression;

expression('math')
.match(':number', ':operator', ':number', function(left, operator, right){
switch (operator) {
case '+': return left + right;
case '-': return left - right;
case '*': return left * right;
case '/': return left / right;
}
});

expression('number')
.match(/\d+/, parseInt);

expression('operator')
.match('+')
.match('-')
.match('*')
.match('/');

var val = grammar.parse('6*8'); // 42
``````

``````function parse(str, expression, position) {
var result = [];

expression.matchers.forEach(function(matcher){
matcher.tokens.forEach(function(token){
var val;
if (token.expression) {
val = parse(str, token.expression, position);
} else {
val = token.parse(str, position);
}
if (val) result.push(val);
});
});

return result;
}

parse('6*8', grammar.root, 0);
``````

``````while (token = stack.pop()) {
val = token.parse(val);
if (val) result.push(val);
}
``````

## 2 个回复2

### ===============>>#2 票数：1

VBA中的（阶乘）方法（因为goto而更清晰）。

``````Option Explicit
Sub Main()
MsgBox fac(1)
MsgBox fac(5)
End Sub
Function fac(n&)
Dim answer&, level&, stackn&(99)
level = 0
zentry:
If n = 1 Then answer = 1: GoTo zreturn
level = level + 1 ' push n
stackn(level) = n
n = n - 1 ' call fac(n-1)
GoTo zentry
zreturn:
If level = 0 Then fac = answer: Exit Function
n = stackn(level) ' pop n
level = level - 1
answer = n * answer ' factorial
GoTo zreturn
End Function
``````

javascript中的相同方法。

``````console.log(fac(1));
console.log(fac(5));
function fac(n) { // non-recursive
var stackn = [];
level = 0;
while (true) { // no goto's
if (n == 1) { answer = 1; break; }
level = level + 1; // push n
stackn[level] = n;
n = n - 1; } // call fac(n-1)
while (true) { // no goto's
if (level == 0) { return answer; }
n = stackn[level]; // pop n
level = level - 1;
answer = n * answer; } // factorial
}
``````