zaach / jison

Bison in JavaScript.
http://jison.org
4.33k stars 449 forks source link

Fails to browserify jison generated parsers #300

Open nahidakbar opened 8 years ago

nahidakbar commented 8 years ago

TypeError: Object # has no method 'apply' at walk (/home/path/node_modules/brfs/node_modules/static-module/node_modules/static-eval/index.js:89:27) at walk (/home/path/node_modules/brfs/node_modules/static-module/node_modules/static-eval/index.js:92:23) at walk (/home/path/node_modules/brfs/node_modules/static-module/node_modules/static-eval/index.js:77:26) at walk (/home/path/node_modules/brfs/node_modules/static-module/node_modules/static-eval/index.js:85:25) at module.exports (/home/path/node_modules/brfs/node_modules/static-module/node_modules/static-eval/index.js:114:7) at traverse (/home/path/node_modules/brfs/node_modules/static-module/index.js:256:23) at walk (/home/path/node_modules/brfs/node_modules/static-module/index.js:208:13) at walk (/home/path/node_modules/brfs/node_modules/static-module/node_modules/falafel/index.js:49:9) at /home/path/node_modules/brfs/node_modules/static-module/node_modules/falafel/index.js:46:17 at forEach (/home/path/node_modules/brfs/node_modules/static-module/node_modules/falafel/node_modules/foreach/index.js:12:16)

I have one line of code: var formula = require("./formula"); and I am using the calculator example from the website.

deathcap commented 8 years ago

Just hit this issue myself, proposed this fix in static-eval:

https://github.com/substack/static-eval/pull/12 Fix exception instead of failure when parsing CallExpressions

The unbrowserifable (or more accurately, unbrfs-able, since static-eval chokes) code is in the generated command-line tool main function:

exports.main = function commonjsMain(args) {
    if (!args[1]) {
        console.log('Usage: '+args[0]+' FILE');
        process.exit(1);
    }
*   var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
    return exports.parser.parse(source);
};

if jison omits this code (probably not needed when running in the browser - override with opts.moduleMain?), or rewrites it as:

var path = require('path').normalize(args[1]); var source = require('fs').readFileSync(path, "utf8");

or if static-eval integrates https://github.com/substack/static-eval/pull/12, then jison should be browserifable

deathcap commented 8 years ago

If using the jison API, then the unbrowserifiable code can be omitted by passing an alternate mainModule function to the generation options, for example:

var Parser = require('jison').Parser;
var fs = require('fs');
var path = require('path');

var options = {
  mainModule: function() {}
};

var grammar = fs.readFileSync(path.join(__dirname, 'grammar.jison'), 'utf8');
var parser = new Parser(grammar);
var parserSource = parser.generate(options);
fs.writeFileSync(path.join(__dirname, 'grammar.js'), parserSource, 'utf8');

As for the CLI, if https://github.com/zaach/jison/pull/316 is merged then this will work:

jison grammar.jison --moduleMain 'function() {}'
lddubeau commented 7 years ago

This is also a problem when using webpack to incorporate a jison-generated module into a build.

(By the way, moduleMain: function() {}, not mainModule: ....)

Ultimately, what I'd like to see is the capability to completely turn off the generation of code that pertains to calling a "main function". Perhaps setting moduleMain: null would could mean "I don't want a main" and the whole code, including the if test that calls exports.main, could be omitted from the generated module.

twheys commented 5 years ago

I would be very happy with a compiler flag to just disable including the main function export

twheys commented 5 years ago

After a bit of scanning through the source code, I found that running jison -m js parser.jison generated output that did not include the commonJS main function.

andyvanee commented 4 years ago

Although this may be a stale issue, I just wanted to add that I found a way around this by using a custom generator script which uses the js module type and exports the resulting variable which produces a valid es6 module.

import { readFileSync, writeFileSync } from "fs"
import jison from "jison"

const moduleName = "parser"

const source = new URL("../parser/grammar.jison", import.meta.url).pathname
const dest = new URL("../parser/grammar.js", import.meta.url).pathname

const grammar = readFileSync(source, "utf8")
const parser = new jison.Parser(grammar)

const parserSource = parser.generate({ moduleType: "js", moduleName })
writeFileSync(dest, `${parserSource}\nexport {${moduleName}}`)

I run this generator is run prior to bundling the whole thing with rollup using the following:

node --experimental-modules --no-warnings parser/generate.js

Hopefully this helps anyone stuck on this issue!