什么是jison

jison是一个用JavaScript语言实现的一个语法分析器生成器。跟Bison Yacc类似,不过jison是用JavaScript实现的。

安装

npm install jison -g

通过命令行使用

克隆github上的示例代码:

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

通过下面的命令生成一个计算器的解析器

jison calculator.jison

将会在当前命令下生成一个calculator.js的JavaScript计算器解析器文件,可以通过下面的命令进行测试。

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

上面执行结果将会输出 4194304

通过commonjs模块使用

你也可以通过JavaScript来生成一段语法分析器程序,假设jison已经存在你的commonjs规范的环境(比如node)

// mygenerator.js
var Parser = require("jison").Parser;

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

    "bnf": {
        "hex_strings" :[ "hex_strings HEX",
                         "HEX" ]
    }
};

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

parser.parse("adfe34bc e82a");
// returns true

parser.parse("adfe34bc zxg");
// throws lexical error

另外,如果你想使用jison文件格式而不是生成一个静态JavaScript文件的话,你可以用下面的一段代码:

// myparser.js
var fs = require("fs");
var jison = require("jison");

var bnf = fs.readFileSync("grammar.jison", "utf8");
var parser = new jison.Parser(bnf);

module.exports = parser;

使用生成的分析器

一旦你生成并保存解析器文件(一个js文件),就不再需要jison以及其他依赖库了。

如前所演示,该解析器可以从命令行中使用:

node calculator.js testcalc

然而,更理想的情况是:解析器可以作为另一个模块的依赖,你可以像下面的写法那样从另一个模块中依赖使用:

// mymodule.js
var parser = require("./calculator").parser;

function exec (input) {
    return parser.parse(input);
}

var twenty = exec("4 * 5");

或者,更简单的写法如下:

Or more succinctly:

// mymodule.js
function exec (input) {
    return require("./calculator").parse(input);
}

var twenty = exec("4 * 5");

在web环境中使用解析器

生成的解析器脚本可能会在没有加载commonjs的web环境中使用,可以通过一个简单的script标签引入到web页面中使用:

<script src="calculator.js"></script>

当您生成语法分析器时,可以指定将其声明为:

// mygenerator.js
var parserSource = generator.generate({moduleName: "calc"});
// then write parserSource to a file called, say, calc.js

你可以通过定义的模块名作为变量名来访问页面中的解析器

<script src="calc.js"></script>
<script>
  calc.parse("42 / 0");
</script>

模块名也可以包含命名空间

// mygenerator.js
var parserSource = parser.generate({moduleName: "myCalculator.parser"});

然后可以像下面那样使用

<script>
  var myCalculator = {};
</script>

<script src="calc.js"></script>

<script>
  myCalculator.parser.parse("42 / 0");
</script>