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 regexEscape = function(s) {
return s.replace(/[\^\\$*+?.()|{}\[\]\/]/g, '\\$&') }
var handleLicensesAndExceptions = function() {
var ids = require('spdx-license-ids')
var exceptions = require('spdx-exceptions')
// Sort tokens longest-first (both license ids and exception strings)
var tokens = ids.concat(exceptions)
tokens.sort(function(a, b) { return ( b.length - a.length ) })
return tokens.map(function(t) {
var type = ( (ids.indexOf(t) >= 0) ? 'LICENSE' : 'EXCEPTION' )
return [ regexEscape(t), ( 'return ' + quote(type) ) ] }) }
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(handleLicensesAndExceptions()) },
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())