I came up with this simple experiment after reading the documentation on generators from MDN:
var nodes = {
type: 'root',
value: [
{ type: 'char', value: 'a' },
{ type: 'char', value: 'b' },
{ type: 'char', value: 'c' },
],
};
function* recursiveGenerator(node) {
if (node.type === 'root') {
node.value.forEach(function (subnode) {
for (var suffix of recursiveGenerator(subnode)) {
yield suffix;
}
});
}
else {
yield node.value;
}
}
for (generated of recursiveGenerator(nodes)) {
console.log(generated);
}
Running it on node.js v0.11.9 with the --harmony
flag set produces the following error:
alix@900X4C:~$ node --version
v0.11.9
alix@900X4C:~$ node --harmony test.js
/home/alix/test.js:14
yield suffix;
^^^^^^
SyntaxError: Unexpected identifier
I also tried using for ... in ...
and the let
keyword instead of var
, but without any success.
I don't understand what yield*
does exactly, but if I use it within the for
loop I get instead:
alix@900X4C:~$ node --harmony test.js
/home/alix/test.js:14
yield* suffix;
^
ReferenceError: yield is not defined
If I replace the yield in the for with console.log()
it outputs a
, b
and c
. What am I doing wrong?
Here's a minimalistic generator, showing that node.js knows what to do with generators:
function* alpha() {
yield 'a';
yield 'b';
yield 'c';
}
for (var suffix of alpha()) {
console.log(suffix);
}
Output:
alix@900X4C:~$ node --harmony y.js
a
b
c
function* recursiveGenerator(node) {
if (node.type === 'root') {
for (var i = 0; i < node.value.length; ++i) {
var subnode = node.value[i];
for (var suffix of recursiveGenerator(subnode)) {
yield suffix;
}
}
}
else {
yield node.value;
}
}
for (generated of recursiveGenerator(nodes)) {
console.log(generated);
}
In this post, we looked at what causes the Uncaught SyntaxError: Unexpected identifier error and how to fix it. In most cases, it is just code that is not adhering to the JavaScript syntax rules or contains typos. Hopefully, this post has helped you with your code!
If you go an run it now as node server.js, you'll get an error SyntaxError: Unexpected token import. It happens because we don't "babelify" our node.js code on the fly yet.
As of now, Node.js doesn't support ES6 imports yet. However, you can use them today with the help of Babel. The following example is for the express.js server. 1. Install necessary packages 2. Tweak your server.js Here's an example server.js:
What causes this error? Since JavaScript is not a compiled language, you can get syntax errors when running your code. One of these errors is the Uncaught SyntaxError: Unexpected identifier error. In this post, we'll look at what causes this, examples of it, and how to fix it. What causes this error? This error is mainly caused by three things.
Summarizing the comments: you can't use yield
inside a regular function, so you can't use yield
with forEach
. Here an example of "generatorized" foreach:
function * foreach (arr, fn) {
var i
for (i = 0; i < arr.length; i++) {
yield * fn(arr[i])
}
}
function * gen (number) {
yield number + 1
yield number + 2
yield number + 3
}
function * other () {
yield * foreach([1, 2, 3], gen)
}
for (var i of other()) {
console.log(i)
}
UPDATE Also the original problem can be solved quite elegantly using such a helper:
var nodes = {
type: 'root',
value: [
{ type: 'char', value: 'a' },
{ type: 'char', value: 'b' },
{ type: 'root', value: [
{ type: 'char', value: 'c' },
{ type: 'char', value: 'd' },
{ type: 'char', value: 'e' },
]
},
],
}
function * foreach (arr, fn) {
var i
for (i = 0; i < arr.length; i++) {
yield * fn(arr[i])
}
}
function * value (val) {
yield val
}
function * recursiveGenerator(node) {
yield * node.type === 'root' ? foreach(node.value, recursiveGenerator) : value(node.value)
}
for (var generated of recursiveGenerator(nodes)) {
console.log(generated);
}
So the generator itself becomes a one-liner!
You've found your solution, but just for the record here is another example a little different that print the types of all nodes in the tree (I added some deepness and vars)
var nodes = {
type: 'root',
value: [
{ type: 'char', value: 'a' },
{ type: 'char', value: 'b' },
{ type: 'char', value: [{type: 'int', value: 'c'}] },
],
};
var flattenTree = function* (root) {
yield root.type;
var subvalues = root.value;
for(var i in subvalues) {
var gen = flattenTree(subvalues[i]);
val = gen.next();
while(!val.done) {
if(val.value != undefined)
yield val.value;
val = gen.next();
}
}
}
var printTree = function() {
console.log("begin tree");
var generator = flattenTree(nodes);
var next = generator.next();
while(!next.done) {
console.log(next);
next = generator.next();
}
console.log("finish tree");
}
printTree();
Outputs:
~/workspace/tmp$ ../node/node --harmony test-gen.js
begin tree
{ value: 'root', done: false }
{ value: 'char', done: false }
{ value: 'char', done: false }
{ value: 'char', done: false }
{ value: 'int', done: false }
finish tree
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With