-
Notifications
You must be signed in to change notification settings - Fork 19
/
peg-rd.js
89 lines (73 loc) · 2.23 KB
/
peg-rd.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
var whitescape = require('whitescape');
var rd = require('./rd');
var pegUtils = require('./peg-utils');
module.exports = function diagram(expr) {
switch (expr.type) {
case 'rule':
// rules = expression
return rd.Diagram(diagram(expr.expression));
/* eslint-disable no-fallthrough */
case 'text':
// $expression
case 'labeled':
// label : expression
case 'named':
// rule "name" = expression
case 'action':
// expression {action}
return diagram(expr.expression);
/* eslint-enable no-fallthrough */
case 'group':
return diagram(expr.expression);
case 'sequence':
// expression1 expression2 ...
return rd.Sequence.apply(null, expr.elements.map(diagram));
case 'choice':
// expression1 / expression2 / ...
return rd.Choice.apply(null, [0].concat(expr.alternatives.map(diagram)));
case 'optional':
// expression ?
return rd.Optional(diagram(expr.expression));
case 'zero_or_more':
// expression *
return rd.ZeroOrMore(diagram(expr.expression));
case 'one_or_more':
// expression +
return rd.OneOrMore(diagram(expr.expression));
case 'rule_ref':
// rule
return rd.NonTerminal(expr.name);
case 'literal':
// 'literal'
return rd.Terminal(whitescape(expr.value));
case 'class':
// [characters]
return rd.Terminal(pegUtils.stringifyClass(expr, whitescape));
case 'any':
// wildcard
// .
return rd.Terminal('[any character]');
case 'simple_and':
// lookahead
// & expression
return diagram(expr.expression);
case 'simple_not':
// negative lookahead
// ! expression
return rd.Optional(rd.Sequence(rd.End(), diagram(expr.expression)), 'skip');
case 'semantic_and':
// predicate lookahead
// & { predicate }
return rd.Terminal('[match:' + expr.code + ']');
case 'semantic_not':
// negative predicate lookahead
// ! { predicate }
return diagram({
type: 'simple_not',
expression: {type: 'class', rawText: '[match:' + expr.code + ']'}
});
}
var msg = 'Unknown expression:' + expr.type;
console.log(msg, expr);
return rd.Terminal(msg);
};