const Grammar = require('syntax-cli').Grammar; const LLParsingTable = require('syntax-cli').LLParsingTable; const jsdom = require("jsdom"); function getRulesFromDOM(window) { let rules = window.document.querySelectorAll("pre.grammar[id]"); return [].map.call(rules, pre => pre.textContent); } const REGEXP = /(\s*:\n\s*)|\b(integer|float|identifier|string|whitespace|comment|other)\b|(\s*\n\s*)|(ε)/g; function processRules(rules) { return rules.map(rule => { return rule.trim().replace(REGEXP, m => { if (/^(integer|float|identifier|string|whitespace|comment|other)$/.test(m)) { return m.toUpperCase(); } if (/:\n/.test(m)) { return "\n : "; } if (/\n/.test(m)) { return "\n | "; } if (/ε/.test(m)) { return "/* epsilon */"; } }) + "\n ;"; }); } function toBNF(rules) { return "\n\n%%\n\n" + processRules(rules).join("\n"); } var path_to_spec = "../index.html"; jsdom.env({ file: path_to_spec, done: function (err, window) { let rules = getRulesFromDOM(window); let bnf = toBNF(rules); let data = Grammar.dataFromString(bnf, 'bnf') let grammar = Grammar.fromData(data, { mode: "LL1" }); let table = new LLParsingTable({ grammar: grammar }); table.getConflicts(); console.log(table.hasConflicts()); } });