This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
1.4 KiB
57 lines
1.4 KiB
"use strict"; |
|
|
|
var arrays = require("../../utils/arrays"), |
|
GrammarError = require("../../grammar-error"), |
|
asts = require("../asts"), |
|
visitor = require("../visitor"); |
|
|
|
/* |
|
* Reports left recursion in the grammar, which prevents infinite recursion in |
|
* the generated parser. |
|
* |
|
* Both direct and indirect recursion is detected. The pass also correctly |
|
* reports cases like this: |
|
* |
|
* start = "a"? start |
|
* |
|
* In general, if a rule reference can be reached without consuming any input, |
|
* it can lead to left recursion. |
|
*/ |
|
function reportInfiniteRecursion(ast) { |
|
var visitedRules = []; |
|
|
|
var check = visitor.build({ |
|
rule: function(node) { |
|
visitedRules.push(node.name); |
|
check(node.expression); |
|
visitedRules.pop(node.name); |
|
}, |
|
|
|
sequence: function(node) { |
|
arrays.every(node.elements, function(element) { |
|
check(element); |
|
|
|
return !asts.alwaysConsumesOnSuccess(ast, element); |
|
}); |
|
}, |
|
|
|
rule_ref: function(node) { |
|
if (arrays.contains(visitedRules, node.name)) { |
|
visitedRules.push(node.name); |
|
|
|
throw new GrammarError( |
|
"Possible infinite loop when parsing (left recursion: " |
|
+ visitedRules.join(" -> ") |
|
+ ").", |
|
node.location |
|
); |
|
} |
|
|
|
check(asts.findRule(ast, node.name)); |
|
} |
|
}); |
|
|
|
check(ast); |
|
} |
|
|
|
module.exports = reportInfiniteRecursion;
|
|
|