-
Notifications
You must be signed in to change notification settings - Fork 122
/
generator.js
118 lines (101 loc) · 2.51 KB
/
generator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
const generate = require('nearley/lib/generate');
function dedentFunc(func) {
let lines = func.toString().split(/\n/);
if (lines.length === 1) {
return [lines[0].replace(/^\s+|\s+$/g, '')];
}
let indent = null;
let tail = lines.slice(1);
for (let i = 0; i < tail.length; i++) {
let match = /^\s*/.exec(tail[i]);
if (match && match[0].length !== tail[i].length) {
if (indent === null || match[0].length < indent.length) {
indent = match[0];
}
}
}
if (indent === null) {
return lines;
}
return lines.map(function dedent(line) {
if (line.slice(0, indent.length) === indent) {
return line.slice(indent.length);
}
return line;
});
}
function tabulateString(string, indent, options) {
let lines;
if (Array.isArray(string)) {
lines = string;
} else {
lines = string.toString().split('\n');
}
options = options || {};
const tabulated = lines
.map(function addIndent(line, i) {
let shouldIndent = true;
if (i === 0 && !options.indentFirst) {
shouldIndent = false;
}
if (shouldIndent) {
return indent + line;
}
return line;
})
.join('\n');
return tabulated;
}
function serializeSymbol(s) {
if (s instanceof RegExp) {
return s.toString();
} else if (s.token) {
return s.token;
}
return JSON.stringify(s);
}
function serializeRule(rule, builtinPostprocessors) {
let ret = '{';
ret += '"name": ' + JSON.stringify(rule.name);
ret += ', "symbols": [' + rule.symbols.map(serializeSymbol).join(', ') + ']';
if (rule.postprocess) {
if (rule.postprocess.builtin) {
rule.postprocess = builtinPostprocessors[rule.postprocess.builtin];
}
ret +=
', "postprocess": ' +
tabulateString(dedentFunc(rule.postprocess), ' ', {
indentFirst: false,
});
}
ret += '}';
return ret;
}
function serializeRules(rules, builtinPostprocessors) {
return (
'[\n ' +
rules
.map(function(rule) {
return serializeRule(rule, builtinPostprocessors);
})
.join(',\n ') +
'\n]'
);
}
module.exports = function customGenerator(parser) {
let output = `// Custom Walt Grammar Generator
function id(x) { return x[0]; }
module.exports = function() {
${parser.body.join('\n')}
return {
Lexer: ${parser.config.lexer},
ParserRules: ${serializeRules(
parser.rules,
generate.javascript.builtinPostprocessors
)},
ParserStart: ${JSON.stringify(parser.start)}
};
}
`;
return output;
};