-
Notifications
You must be signed in to change notification settings - Fork 11
/
generate-parser.js
120 lines (114 loc) · 2.61 KB
/
generate-parser.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
119
120
// Parser Generator
// ================
// Use jison to generate an SPDX Expression parser based on a
// Bison-style BNF grammar.
var Generator = require('jison').Generator;
var options = {
type: 'slr',
moduleType: 'commonjs',
moduleName: 'spdxparse'
};
var words = ['AND', 'OR', 'WITH'];
var quote = function(argument) {
return '\'' + argument + '\'';
};
var ret = function(token) {
return function(character) {
return [character, 'return ' + quote(token) + ';'];
};
};
var grammar = {
lex: {
macros: {},
rules: [
['$', 'return ' + quote('EOS') + ';'],
['\\s+', '/* skip whitespace */'],
['\\+', 'return ' + quote('PLUS') + ';'],
['\\(', 'return ' + quote('OPEN') + ';'],
['\\)', 'return ' + quote('CLOSE') + ';'],
[':', 'return ' + quote('COLON') + ';'],
[
'DocumentRef-([0-9A-Za-z-+.]+)',
'return ' + quote('DOCUMENTREF') + ';'
],
[
'LicenseRef-([0-9A-Za-z-+.]+)',
'return ' + quote('LICENSEREF') + ';'
]
]
.concat(words.map(function(word) {
return [word, 'return ' + quote(word) + ';'];
}))
.concat(require('spdx-license-ids').map(ret('LICENSE')))
.concat(require('spdx-exceptions').map(ret('EXCEPTION')))
},
operators: [
['left', 'OR'],
['left', 'AND'],
['right', 'PLUS', 'WITH']
],
tokens: [
'CLOSE',
'COLON',
'EXCEPTION',
'LICENSE',
'LICENSEREF',
'OPEN',
'PLUS'
]
.concat(words)
.join(' '),
start: 'start',
bnf: {
start: [
['expression EOS', 'return $$ = $1;']
],
simpleExpression: [
[
'LICENSE',
'$$ = { license: yytext };'
],
[
'LICENSE PLUS',
'$$ = { license: $1, plus: true };'
],
[
'LICENSEREF',
'$$ = { license: yytext };'
],
[
'DOCUMENTREF COLON LICENSEREF',
'$$ = { license: yytext };'
]
],
expression: [
[
'simpleExpression',
'$$ = $1;'
],
[
'simpleExpression WITH EXCEPTION',
[
'$$ = { exception: $3 };',
'$$.license = $1.license;',
'if ($1.hasOwnProperty(\'plus\')) {',
' $$.plus = $1.plus;',
'}'
].join('\n')
],
[
'expression AND expression',
'$$ = { conjunction: \'and\', left: $1, right: $3 };'
],
[
'expression OR expression',
'$$ = { conjunction: \'or\', left: $1, right: $3 };'
],
[
'OPEN expression CLOSE',
'$$ = $2'
]
]
}
};
console.log(new Generator(grammar, options).generate());