updated to latest jison, rebuilt parser

This commit is contained in:
Jeremy Ashkenas 2010-02-11 23:34:45 -05:00
parent 13c49ad865
commit df386a3b3f
3 changed files with 74 additions and 37 deletions

File diff suppressed because one or more lines are too long

View File

@ -355,13 +355,13 @@ lookaheadMixin.followSets = function followSets () {
var ctx = !!self.go_;
var set = [],oldcount;
for (var i=0,n=0,t;t=production.handle[i];++i) {
for (var i=0,t;t=production.handle[i];++i) {
if (!nonterminals[t]) continue;
// for Simple LALR algorithm, self.go_ checks if
if (ctx)
q = self.go_(production.symbol, production.handle.slice(0, i));
var bool = !ctx || q === parseInt(t.split(":")[0]);
var bool = !ctx || q === parseInt(self.nterms_[t]);
if (i === production.handle.length+1 && bool) {
set = nonterminals[production.symbol].follows
@ -369,8 +369,8 @@ lookaheadMixin.followSets = function followSets () {
var part = production.handle.slice(i+1);
set = self.first(part);
if (self.nullable(part) && bool) {
set.push.apply(set, nonterminals[production.symbol].follows);
if (set.length === 0 && bool) { // set was nullable
set = nonterminals[production.symbol].follows;
}
}
oldcount = nonterminals[t].follows.length;
@ -391,10 +391,10 @@ lookaheadMixin.first = function first (symbol) {
// RHS
} else if (symbol instanceof Array) {
var firsts = [];
for (var i=0,n=0,t;t=symbol[i];++i) {
this.first(t).forEach(function (e) {
for (var i=0,t;t=symbol[i];++i) {
this.first(t).forEach(function first_forEach (e) {
if (firsts.indexOf(e)===-1)
firsts.push(e);
firsts.push(e);
});
if (!this.nullable(t))
break;
@ -561,6 +561,25 @@ lrGeneratorMixin.ItemSet = Set.prototype.construct({
this.edges = {};
this.shifts = false;
this.inadequate = false;
this.hash_ = {};
for (var i=this._items.length-1;i >=0;i--) {
this.hash_[this._items[i].id] = true; //i;
}
},
concat: function concat (set) {
var a = set._items || set;
for (var i=a.length-1;i >=0;i--) {
this.hash_[a[i].id] = true; //i;
}
this._items.push.apply(this._items, a);
return this;
},
push: function (item) {
this.hash_[item.id] = true;
return this._items.push(item);
},
contains: function (item) {
return this.hash_[item.id];
},
toValue: function toValue () {
var v = this.items_.sort().join('|');
@ -584,7 +603,7 @@ lrGeneratorMixin.closureOperation = function closureOperation (itemSet /*, closu
// if token is a non-terminal, recursively add closures
if (symbol && self.nonterminals[symbol]) {
if(!syms[symbol]) {
self.nonterminals[symbol].productions.forEach(function CO_forEach (production) {
self.nonterminals[symbol].productions.forEach(function CO_nt_forEach (production) {
var newItem = new self.Item(production, 0);
if(!closureSet.contains(newItem))
itemQueue.push(newItem);
@ -1071,14 +1090,16 @@ var lalr = generator.beget(lookaheadMixin, lrGeneratorMixin, {
type: "LALR(1)",
afterconstructor: function (grammar, options) {
if (this.DEBUG) this.mix(lrGeneratorDebug); // mixin debug methods
if (this.DEBUG) this.mix(lrGeneratorDebug, lalrGeneratorDebug); // mixin debug methods
options = options || {};
this.states = this.canonicalCollection();
this.terms_ = {};
var newg = this.newg = typal.beget(lookaheadMixin,{
oldg: this,
trace: this.trace,
nterms_: {},
DEBUG: false,
go_: function (r, B) {
r = r.split(":")[0]; // grab state #
@ -1113,11 +1134,14 @@ var lalr = generator.beget(lookaheadMixin, lrGeneratorMixin, {
return q;
},
goPath: function LALR_goPath (p, w) {
var q = parseInt(p),
var q = parseInt(p),t,
path = [];
for (var i=0;i<w.length;i++) {
path.push(w[i] ? q+":"+w[i] : '');
t = w[i] ? q+":"+w[i] : '';
if (t) this.newg.nterms_[t] = q;
path.push(t);
q = this.states.item(q).edges[w[i]] || q;
this.terms_[t] = w[i];
}
return {path: path, endState: q};
},
@ -1131,6 +1155,8 @@ var lalr = generator.beget(lookaheadMixin, lrGeneratorMixin, {
if (item.dotPosition === 0) {
// new symbols are a combination of state and transition symbol
var symbol = i+":"+item.production.symbol;
self.terms_[symbol] = item.production.symbol;
newg.nterms_[symbol] = i;
if (!newg.nonterminals[symbol])
newg.nonterminals[symbol] = new Nonterminal(symbol);
var pathInfo = self.goPath(i, item.production.handle);
@ -1140,9 +1166,10 @@ var lalr = generator.beget(lookaheadMixin, lrGeneratorMixin, {
// store the transition that get's 'backed up to' after reduction on path
var handle = item.production.handle.join(' ');
if (!self.states.item(pathInfo.endState).goes[handle])
self.states.item(pathInfo.endState).goes[handle] = [];
self.states.item(pathInfo.endState).goes[handle].push(symbol);
var goes = self.states.item(pathInfo.endState).goes;
if (!goes[handle])
goes[handle] = [];
goes[handle].push(symbol);
//self.trace('new production:',p);
}
@ -1159,12 +1186,19 @@ var lalr = generator.beget(lookaheadMixin, lrGeneratorMixin, {
states.forEach(function union_states_forEach (i) {
var state = typeof i === 'number' ? self.states.item(i) : i,
follows = [];
if (state.reductions.length)
state.reductions.forEach(function union_reduction_forEach (item) {
var follows = {};
for (var k=0;k<item.follows.length;k++) {
follows[item.follows[k]] = true;
}
state.goes[item.production.handle.join(' ')].forEach(function reduction_goes_forEach (symbol) {
newg.nonterminals[symbol].follows.forEach(function goes_follows_forEach (symbol) {
var terminal = symbol.slice(symbol.indexOf(":")+1);
if (item.follows.indexOf(terminal) === -1)
var terminal = self.terms_[symbol];
if (!follows[terminal]) {
follows[terminal]=true;
item.follows.push(terminal);
}
});
});
//self.trace('unioned item', item);
@ -1224,9 +1258,11 @@ var lr1 = lrLookaheadGenerator.beget({
return item.follows;
},
Item: lrGeneratorMixin.Item.prototype.construct({
afterconstructor: function () {
this.id = this.production.id+'a'+this.dotPosition+'a'+this.follows.sort().join(',');
},
eq: function (e) {
return e.production && e.dotPosition !=null && this.production===e.production && this.dotPosition === e.dotPosition &&
this.follows.length === Set.union(e.follows.slice(0),this.follows).length;
return e.id === this.id;
}
}),
@ -1356,6 +1392,7 @@ exports.main = function main (args) {
}
var opt = grammar.options || {};
opt.debug = true;
// lexer file
if (args[2]) {

View File

@ -45,7 +45,7 @@ var setMixin = {
var cont = true;
for (var i=0; i<this._items.length && cont;i++) {
cont = cont && set.contains(this._items[i]);
}
};
return cont;
},
superset: function superset (set) {