Subsecciones

Usando Jison desde un Programa

[~/srcPLgrado/jison/as-a-library]$ cat mygenerator.js
// mygenerator.js
var util = require('util');
var Parser = require("jison").Parser;

var grammar = {
    "tokens" : [ 'HEX' ],
    "lex": {
        "rules": [
           ["\\s+", "/* skip whitespace */"],
           ["[a-f0-9]+", function() { return 'HEX'; }]
        ]
    },

    "bnf": {
        "s": [["hex_strings", "console.log('attr= '+($1)); return $1" ]],
        "hex_strings": [ [ "hex_strings HEX",  function() {
                                                 console.log('h -> h HEX('+$2+')');
                                                 $1.push($2); 
                                                 $$ = $1;
                                               }
                         ],
                         ["HEX", "console.log('h -> HEX('+$1+')'); $$ = [$1];" ] 
                       ]
    },
    "startSymbol" : 's'
};

var parser = new Parser(grammar);

// generate source, ready to be written to disk
var parserSource = parser.generate();

// you can also use the parser directly from memory

var args = process.argv.slice(2).join(' ');
console.log(util.inspect(args));
if (args.length == 0) args = 'adfe34bc e82a';
var res = parser.parse(args);
console.log(util.inspect(res));

[~/srcPLgrado/jison/as-a-library]$ node mygenerator.js 
''
h -> HEX(adfe34bc)
h -> h HEX(e82a)
attr= adfe34bc,e82a
[ 'adfe34bc', 'e82a' ]

[~/srcPLgrado/jison/as-a-library]$ cat calculator.js
// calculator.js
var util = require('util');
var Parser = require("jison").Parser;

var grammar = {
    "tokens": ['NUMBER', 'PI', 'E'],
    "lex": {
        "rules": [
           ["\\s+",                    "/* skip whitespace */"],
           ["[0-9]+(?:\\.[0-9]+)?\\b", "return 'NUMBER';"],
           ["\\*",                     "return '*';"],
           ["\\/",                     "return '/';"],
           ["-",                       "return '-';"],
           ["\\+",                     "return '+';"],
           ["\\^",                     "return '^';"],
           ["\\(",                     "return '(';"],
           ["\\)",                     "return ')';"],
           ["PI\\b",                   "return 'PI';"],
           ["E\\b",                    "return 'E';"],
           ["$",                       "return 'EOF';"]
        ]
    },

    "operators": [
        ["left", "+", "-"],
        ["left", "*", "/"],
        ["left", "^"],
        ["left", "UMINUS"]
    ],

    "bnf": {
        "expressions" :[[ "e EOF",   "console.log($1); return $1;"  ]],

        "e" :[[ "e + e",   "$$ = $1 + $3;" ],
              [ "e - e",   "$$ = $1 - $3;" ],
              [ "e * e",   "$$ = $1 * $3;" ],
              [ "e / e",   "$$ = $1 / $3;" ],
              [ "e ^ e",   "$$ = Math.pow($1, $3);" ],
              [ "- e",     "$$ = -$2;", {"prec": "UMINUS"} ],
              [ "( e )",   "$$ = $2;" ],
              [ "NUMBER",  "$$ = Number(yytext);" ],
              [ "E",       "$$ = Math.E;" ],
              [ "PI",      "$$ = Math.PI;" ]]
    }
}

var parser = new Parser(grammar);

// generate source, ready to be written to disk
var parserSource = parser.generate();

// you can also use the parser directly from memory

var args = process.argv.slice(2).join(' ');
console.log(util.inspect(args));
if (args.length == 0) args = '2+3*4';
var res = parser.parse(args);
console.log(util.inspect(res));

[~/srcPLgrado/jison/as-a-library]$ node calculator.js '2*3+5'
'2*3+5'
11
11

[~/srcPLgrado/jison/as-a-library]$ cat mygenerator.coffee 
# mygenerator.coffee
util = require('util')
Parser = require('jison').Parser
grammar = ''' 
%lex 
%%
\\s+         /* skip whitespace */
[a-f0-9]+    return 'HEX'
/lex

%%
s: hex_strings { console.log('attr= '+$1); return $1 }
;
hex_strings: hex_strings HEX { console.log('h -> h HEX('+$2+')'); 
                               $1.push($2); $$ = $1;
                             }
           | HEX { console.log('h -> HEX('+$1+')'); 
                   $$ = [$1]; 
                 }
;
'''
parser = new Parser grammar
# generate source, ready to be written to disk
parserSource = parser.generate()
# you can also use the parser directly from memory
args = process.argv.slice(2).join(' ')
console.log util.inspect(args)
if args.length is 0
  args = 'adfe34bc e82a'
res = parser.parse(args)
console.log util.inspect(res)

[~/srcPLgrado/jison/as-a-library]$ coffee mygenerator.coffee '32e 4f'
'32e 4f'
h -> HEX(32e)
h -> h HEX(4f)
attr= 32e,4f
[ '32e', '4f' ]

Véase

Casiano Rodríguez León
2016-03-27