# Jison: from a Bison-style grammar to a JavaScript parser

> Jison reads a Bison-style or JSON grammar and writes a JavaScript parser you can run on Node or bundle for a browser. The generator is small and the grammar format is familiar, but the pinned dependencies are old enough to shape the adoption decision.

**zaach/jison** — GitHub describes it as Bison in JavaScript.. The repository metadata lists JavaScript as its primary language. This article stays within the project description and details documented in the GitHub repository README.

- Repository: https://github.com/zaach/jison
- Website: http://jison.org
- Stars: 4,380 · Forks: 452
- Language: JavaScript
- License: not declared
- Published: 2026-08-13 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/zaach-jison

## One grammar file in, a parser JavaScript file out

Jison exists for the case where a language is small enough to describe with a context-free grammar and awkward enough that hand-writing a recursive descent parser is a bad afternoon. You describe the language in a Bison-style `.jison` file or in JSON, run the generator, and receive a JavaScript file that parses input for that language. The generated parser accepts, rejects, or runs semantic actions, which is the same three-way outcome a hand-written parser gives you, with the grammar written down in one place instead of spread across functions.

The audience is narrow and identifiable: JavaScript developers who already know Bison, or who are willing to read the Bison manual the README points them at. That manual is the deliberate fallback for anyone new to parser generators, and the README says so in as many words. If you have never written a grammar, the documentation sends you to dinosaur.compilertools.net before it teaches you anything about JavaScript, which tells you the learning curve lives in the grammar, not in the tool.

The repository itself is laid out like a compiler toolchain rather than a library: `lib/` holds the generator, `tests/` the suite, `examples/` around twenty grammars including `calculator.jison`, `classy.jison`, `precedence.jison` and `reduce_conflict.jison`, and `ports/` and `web/` hold the site build. The presence of `examples/reduce_conflict.jison` and `examples/dism_lr0.jison` in the top level is a fair signal about which problems the author expected you to hit.

## The -p flag picks one of four parsing algorithms

The CLI is small enough to read in one screen, and the design of the generator is exposed in it. Two positional arguments: a file containing a grammar, and optionally a file containing a lexical grammar. Then six options, of which one decides the shape of the parser you get:

```bash
-p TYPE, --parser-type TYPE   The type of algorithm to use for the parser (lr0, slr, lalr, lr)
```

That one choice trades parser power against how much ambiguity the generator will tolerate. lr0 is the cheapest and the least capable, slr widens the lookahead, lalr is the middle road most grammars land on, and lr takes the broadest set of grammars at higher generation cost. The `examples/dism_lr0.jison` file exists to be built with the weakest algorithm, so you can watch it fall over on a grammar that needs more.

The other flags change plumbing rather than theory. `-o FILE, --outfile FILE` sets both the output filename and the base module name, `-m TYPE, --module-type TYPE` picks between commonjs, amd and js output so the generated file drops into a build, and `-j, --json` tells the generator to read the grammar as JSON instead of parsing the `.jison` syntax. With no output flag given, the result lands in your current working directory under the grammar's own name.

## Generating calculator.js and feeding it an expression

The README's own path is to clone the repository and build a bundled example, which is also the quickest way to see whether the tool runs on your machine at all.

```bash
npm install jison -g
```

That installs globally, which suits a code generator you invoke on grammar files rather than a runtime dependency of your app. Then get the examples:

```bash
git clone git://github.com/zaach/jison.git
cd jison/examples
```

From there, two commands produce a working parser and prove it:

```bash
jison calculator.jison
```

This writes `calculator.js` in the current working directory. The calculator grammar handles the `^` operator, which is why the README picks that example rather than something simpler. Feed it an expression and the parser evaluates it:

```bash
echo "2^32 / 1024" > testcalc
node calculator.js testcalc
```

The documented result is `4194304`. That output is the whole pitch in two lines: you write the operator precedence once, in the grammar, and the generated JavaScript does the arithmetic.

## Lexing lives in a separate file and a separate package

Jison does not bundle its lexer into the grammar parser. Tokenizing is handled by `jison-lex`, pinned at `0.3.x` in the dependencies, and it can be supplied either as an inline lex section, as the JSON grammar in the README's JavaScript example shows, or as a second file passed on the command line as the lexfile argument. The example directory keeps both styles side by side in `basic_lex.jison`, `basic2_lex.jison` and the standalone `classy.jisonlex`, so you can read all three conventions without guessing.

Writing the lexer inline means the grammar object carries both halves, and constructing a `Parser` from it compiles them together. Passing a lexfile means the tokens live outside the grammar and the generator reads a second input. The inline form is the shorter path for a small language. The two-file form is the one you want when the same lexer feeds several grammars.

The inline example also shows where semantic actions go, as JavaScript strings in an array rather than as tagged blocks:

```javascript
var Parser = require("jison").Parser;
```

Whitespace in that example is not a rule with an action, it is a rule whose action is a comment saying to skip whitespace. That detail is the guide to how the whole action system works: actions are code fragments the generator splices into the parser it writes.

## Old pins in package.json are the real adoption cost

The generator's dependency list is where adopters get hurt, and it is worth reading before you commit. `esprima` is pinned at `1.1.x` and `escodegen` at `1.3.x`, both from the era when the project was written. `nomnom` sits at exactly `1.5.2`, and `JSONSelect` at `0.4.0`. The devDependencies go further back still, with `browserify` at `2.x.x` and `uglify-js` at `~2.4.0`, which is what the Makefile uses to build the browser bundle of the site. Those pins are old enough that an install can resolve them differently than the author ever did.

The `engines` field says `>=0.4`, which is permissive enough that it will not stop you on a modern Node, but it is also a claim that nothing has been checked since that era. There is a second-order catch here: the devDependencies list `jison` at `0.4.x` as a dependency of its own test suite, while `package.json` records the working version as `0.4.18`. The test entry point is `node tests/all-tests.js`, which the Makefile wires to its test target. Running the suite therefore installs an old published copy of the generator instead of exercising the working tree.

The licence is not a worry: package.json names MIT and the README carries the same MIT text under a 2009-2014 Zachary Carter copyright, though the last push to the repository was on 2022-10-14 and there are no GitHub releases, so nothing tells you which published version matches the source you cloned. Pin a version in your own package.json rather than trusting a global install for a reproducible build.

## Reading examples/ as the missing tutorial

The documentation link in the README points to jison.org/docs, but the examples directory carries more of the teaching load than any prose. Around twenty grammars sit there, and the filenames read like a table of contents: `basic.jison` and `basic2.jison` for the smallest cases, `precedence.jison` for how operators are ranked, `lambdacalc.jison` for a grammar with real actions, `dism.jison` paired with `dism_lr0.jison` for the same language at two parser strengths, and `reduce_conflict.jison` for what ambiguity looks like when you ask the generator for it.

Two of them have sibling source files rather than grammars: `classy_test.src` and `semwhitespace_ex.src` are the input that goes into `classy.jison` and `semwhitespace.jison`. That pairing is the practical lesson, because it shows the intended workflow is a grammar plus a small fixture you keep next to it and regenerate against.

Files such as `inherited.y` are the direct Bison connection. A yacc grammar kept alongside the Jison grammars is there to show that the two read the same productions, which is the claim the project's name makes, and it is the file to open if you are porting a grammar rather than writing one.

## Where Jison parts ways with Bison itself

Jison is named for Bison because it copies Bison's API, and the real difference is in what comes out the other end. Bison takes a yacc grammar and generates a C parser, which then needs a C toolchain, a build step and a lex implementation such as flex, and the example grammar `examples/inherited.y` in this repository is kept around to show the shared syntax. Jison takes the same grammar shape and emits JavaScript, so the result runs under Node with no compile step, and the same `Parser` object that generated the file can be used directly from memory without ever touching disk.

That difference is what makes Jison interesting for browser-bound grammars, and the `Makefile` shows the intended path: `browserify entry.js --exports require` piped through `uglifyjs` produces a single `jison.js` under `web/content/assets/js/`. A grammar that ships to a client is a grammar that had to be parsed at runtime, which is exactly the case where generating C buys nothing.

Where the two do not differ is conflict handling. The existence of `examples/reduce_conflict.jison` in the examples directory says the interesting cases are the ambiguous ones, and no flag in the option list resolves them for you. Grammar design stays your job, in either tool.

## Conclusion

Adopt Jison when a grammar is the hard part of your build, when the parser has to run under Node or in a browser with no compile step, and when you already think in yacc syntax or are willing to read the Bison manual. Do not adopt it if you need a maintained native parser generator, if your team cannot carry a dependency refresh, or if you expect conflict resolution to be handled for you: Jison reports ambiguous grammars and leaves the fix in your hands. Before committing, install the tool and build the bundled `examples/calculator.jison`, then check the generated parser against your own input. If that example runs and your grammar produces no shift or reduce conflict warnings, you are in good shape; if the install trips over the old pins in package.json, decide then whether you want to own that refresh.

## FAQ

### What is jison?

Jison is a parser generator with Bison's API that takes a Bison-style or JSON encoded grammar and outputs a JavaScript file capable of parsing the language that grammar describes.

### How do I install jison?

The README gives one route, installing the command line tool globally for Node with `npm install jison -g`, which puts the `jison` binary on your path.

### Which parsing algorithms can jison generate?

The parser-type option accepts lr0, slr, lalr and lr, so you can choose how much lookahead and how much ambiguity the generated parser tolerates.

### Can jison read a JSON grammar instead of a .jison file?

Yes. Pass `-j, --json` to make the generator expect JSON, or construct the grammar object in JavaScript and hand it to `new Parser(grammar)`, with lex rules and BNF productions in the same object.

### What Node.js version does jison require?

The `engines` field in package.json asks for `>=0.4`, which places no upper bound on the Node version you run it under.

## Sources

- [Official documentation](http://jison.org)
- [Official README](https://github.com/zaach/jison#readme)
- [Project repository](https://github.com/zaach/jison)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/zaach-jison
