mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
updated to latest jison, rebuilt parser
This commit is contained in:
parent
13c49ad865
commit
df386a3b3f
3 changed files with 74 additions and 37 deletions
File diff suppressed because one or more lines are too long
95
vendor/jison/lib/jison.js
vendored
95
vendor/jison/lib/jison.js
vendored
|
@ -208,7 +208,7 @@ generator.buildProductions = function buildProductions(bnf, productions, nonterm
|
|||
if (handle.constructor === Array) {
|
||||
if (typeof handle[0] === 'string')
|
||||
rhs = handle[0].trim().split(' ');
|
||||
else
|
||||
else
|
||||
rhs = handle[0].slice(0);
|
||||
|
||||
for (i=0; i<rhs.length; i++) if (!symbols_[rhs[i]]) {
|
||||
|
@ -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
|
||||
// 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;
|
||||
|
@ -534,7 +534,7 @@ lrGeneratorMixin.Item = typal.construct({
|
|||
constructor: function Item(production, dot, f, predecessor) {
|
||||
this.production = production;
|
||||
this.dotPosition = dot || 0;
|
||||
this.follows = f || [];
|
||||
this.follows = f || [];
|
||||
this.predecessor = predecessor;
|
||||
this.id = parseInt(production.id+'a'+this.dotPosition, 36);
|
||||
this.markedSymbol = this.production.handle[this.dotPosition];
|
||||
|
@ -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);
|
||||
|
@ -654,7 +673,7 @@ lrGeneratorMixin.canonicalCollectionInsert = function canonicalCollectionInsert
|
|||
var i = states.indexOf(g);
|
||||
if (i === -1) {
|
||||
itemSet.edges[symbol] = states.size(); // store goto transition for table
|
||||
states.push(g);
|
||||
states.push(g);
|
||||
g.predecessors[symbol] = [stateNum];
|
||||
} else {
|
||||
itemSet.edges[symbol] = i; // store goto transition for table
|
||||
|
@ -686,7 +705,7 @@ lrGeneratorMixin.parseTable = function parseTable (itemSets) {
|
|||
if (nonterminals[stackSymbol]) {
|
||||
// store state to go to after a reduce
|
||||
//self.trace(k, stackSymbol, 'g'+gotoState);
|
||||
state[self.symbols_[stackSymbol]] = gotoState;
|
||||
state[self.symbols_[stackSymbol]] = gotoState;
|
||||
} else {
|
||||
//self.trace(k, stackSymbol, 's'+gotoState);
|
||||
state[self.symbols_[stackSymbol]] = [[s,gotoState]];
|
||||
|
@ -699,7 +718,7 @@ lrGeneratorMixin.parseTable = function parseTable (itemSets) {
|
|||
itemSet.forEach(function (item, j) {
|
||||
if (item.markedSymbol == self.EOF) {
|
||||
// accept
|
||||
state[self.symbols_[self.EOF]] = [[a]];
|
||||
state[self.symbols_[self.EOF]] = [[a]];
|
||||
//self.trace(k, self.EOF, state[self.EOF]);
|
||||
}
|
||||
});
|
||||
|
@ -899,7 +918,7 @@ lrGeneratorMixin.createParser = function createParser () {
|
|||
var p = parser.beget();
|
||||
|
||||
p.init({
|
||||
table: this.table,
|
||||
table: this.table,
|
||||
productions_: this.productions_,
|
||||
symbols_: this.symbols_,
|
||||
terminals_: this.terminals,
|
||||
|
@ -955,7 +974,7 @@ parser.parse = function parse (input) {
|
|||
};
|
||||
|
||||
var symbol, state, action, a, r, yyval={},p,len,ip=0,newState, expected;
|
||||
symbol = lex();
|
||||
symbol = lex();
|
||||
while (true) {
|
||||
this.trace('stack:',JSON.stringify(stack), '\n\t\t\tinput:', this.lexer._input);
|
||||
this.trace('vstack:',JSON.stringify(vstack));
|
||||
|
@ -982,7 +1001,7 @@ parser.parse = function parse (input) {
|
|||
throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
|
||||
}
|
||||
|
||||
a = action[0];
|
||||
a = action[0];
|
||||
|
||||
switch (a[0]) {
|
||||
|
||||
|
@ -993,7 +1012,7 @@ parser.parse = function parse (input) {
|
|||
yyleng = this.lexer.yyleng;
|
||||
yytext = this.lexer.yytext;
|
||||
yylineno = this.lexer.yylineno;
|
||||
symbol = lex();
|
||||
symbol = lex();
|
||||
vstack.push(null); // semantic values or junk only, no terminals
|
||||
stack.push(a[1]); // push state
|
||||
break;
|
||||
|
@ -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);
|
||||
|
@ -1190,7 +1224,7 @@ var lalrGeneratorDebug = {
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
* Lookahead parser definitions
|
||||
*
|
||||
* Define base type
|
||||
|
@ -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]) {
|
||||
|
|
8
vendor/jison/lib/jison/util/set.js
vendored
8
vendor/jison/lib/jison/util/set.js
vendored
|
@ -12,11 +12,11 @@ var setMixin = {
|
|||
this._items = [].slice.call(arguments,0);
|
||||
},
|
||||
concat: function concat (setB) {
|
||||
this._items.push.apply(this._items, setB._items || setB);
|
||||
return this;
|
||||
this._items.push.apply(this._items, setB._items || setB);
|
||||
return this;
|
||||
},
|
||||
eq: function eq (set) {
|
||||
return this._items.length === set._items.length && this.subset(set);
|
||||
return this._items.length === set._items.length && this.subset(set);
|
||||
},
|
||||
indexOf: function indexOf (item) {
|
||||
if(item && item.eq) {
|
||||
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue