jison's notebooks

  • util - /jison/util
    Last edited 5 years ago
    function each (obj, func) { if (obj.forEach) { obj.forEach(func); } else { var p; for (p in obj) { if (obj.hasOwnProperty(p)) { func.call(obj, obj[p], p, obj); } } } } function processOperators (ops) { if (!ops) return {}; var operators = {}; for (var i=0,k,prec;prec=ops[i]; i++) { for (k=1;k < prec.length;k++) { operators[prec[k]] = {precedence: i+1, assoc: prec[0]}; } } return operators; } module.exports = {each, processOperators}
  • set - /jison/set
    Last edited 5 years ago
    // Set class to wrap arrays var typal = require("@runkit/jison/typal/1.0.1"); var setMixin = { constructor: function Set_constructor (set, raw) { this._items = []; if (set && set.constructor === Array) this._items = raw ? set: set.slice(0); else if(arguments.length) this._items = [].slice.call(arguments,0); }, concat: function concat (setB) { 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); }, indexOf: function indexOf (item) { if(item && item.eq) { for(var k=0; k<this._items.length;k++) if(item.eq(this._items[k])) return k; return -1; } return this._items.indexOf(item); }, union: function union (set) { return (new Set(this._items)).concat(this.complement(set)); }, intersection: function intersection (set) { return this.filter(function (elm) { return set.contains(elm); }); }, complement: function complement (set) { var that = this; return set.filter(function sub_complement (elm) { return !that.contains(elm); }); }, subset: function subset (set) { 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) { return set.subset(this); }, joinSet: function joinSet (set) { return this.concat(this.complement(set)); }, contains: function contains (item) { return this.indexOf(item) !== -1; }, item: function item (v, val) { return this._items[v]; }, i: function i (v, val) { return this._items[v]; }, first: function first () { return this._items[0]; }, last: function last () { return this._items[this._items.length-1]; }, size: function size () { return this._items.length; }, isEmpty: function isEmpty () { return this._items.length === 0; }, copy: function copy () { return new Set(this._items); }, toString: function toString () { return this._items.toString(); } }; "push shift unshift forEach some every join sort".split(' ').forEach(function (e,i) { setMixin[e] = function () { return Array.prototype[e].apply(this._items, arguments); }; setMixin[e].name = e; }); "filter slice map".split(' ').forEach(function (e,i) { setMixin[e] = function () { return new Set(Array.prototype[e].apply(this._items, arguments), true); }; setMixin[e].name = e; }); var Set = typal.construct(setMixin).mix({ union: function (a, b) { var ar = {}; for (var k=a.length-1;k >=0;--k) { ar[a[k]] = true; } for (var i=b.length-1;i >= 0;--i) { if (!ar[b[i]]) { a.push(b[i]); } } return a; } }); module.exports.Set = Set;
  • grammars - /jison/grammars
    Last edited 5 years ago
    let basic = ` %% E : E PLUS T | T ; T : ZERO ; ` let calc = ` %lex %% \s+ /* skip whitespace */ [0-9]+("."[0-9]+)?\b return 'NUMBER' "*" return '*' "/" return '/' "-" return '-' "+" return '+' "^" return '^' "!" return '!' "%" return '%' "(" return '(' ")" return ')' "PI" return 'PI' "E" return 'E' <<EOF>> return 'EOF' . return 'INVALID' /lex /* operator associations and precedence */ %left '+' '-' %left '*' '/' %left '^' %right '!' %right '%' %left UMINUS %start expressions %% /* language grammar */ expressions : e EOF { typeof console !== 'undefined' ? console.log($1) : print($1); return $1; } ; e : e '+' e {$ = $1+$3;} | e '-' e {$ = $1-$3;} | e '*' e {$ = $1*$3;} | e '/' e {$ = $1/$3;} | e '^' e {$ = Math.pow($1, $3);} | e '!' {{ $ = (function fact (n) { return n==0 ? 1 : fact(n-1) * n })($1); }} | e '%' {$ = $1/100;} | '-' e %prec UMINUS {$ = -$2;} | '(' e ')' {$ = $2;} | NUMBER {$ = Number(yytext);} | E {$ = Math.E;} | PI {$ = Math.PI;} ; ` let classy = ` /* description: ClassyLang grammar. Very classy. */ /* To build parser: $ ./bin/jison examples/classy.jison examples/classy.jisonlex */ /* author: Zach Carter */ %right ASSIGN %left OR %nonassoc EQUALITY GREATER %left PLUS MINUS %left TIMES %right NOT %left DOT %% pgm : cdl MAIN LBRACE vdl el RBRACE ENDOFFILE ; cdl : c cdl | ; c : CLASS id EXTENDS id LBRACE vdl mdl RBRACE ; vdl : VAR t id SEMICOLON vdl | ; mdl : t id LPAREN t id RPAREN LBRACE vdl el RBRACE mdl | ; t : NATTYPE | id ; id : ID ; el : e SEMICOLON el | e SEMICOLON ; e : NATLITERAL | NUL | id | NEW id | THIS | IF LPAREN e RPAREN LBRACE el RBRACE ELSE LBRACE el RBRACE | FOR LPAREN e SEMICOLON e SEMICOLON e RPAREN LBRACE el RBRACE | READNAT LPAREN RPAREN | PRINTNAT LPAREN e RPAREN | e PLUS e | e MINUS e | e TIMES e | e EQUALITY e | e GREATER e | NOT e | e OR e | e DOT id | id ASSIGN e | e DOT id ASSIGN e | id LPAREN e RPAREN | e DOT id LPAREN e RPAREN | LPAREN e RPAREN ; ` let lambda = ` %lex %% \s*\n\s* {/* ignore */} "(" { return '('; } ")" { return ')'; } "^"|"λ" { return 'LAMBDA'; } "."\s? { return '.'; } [a-zA-Z] { return 'VAR'; } \s+ { return 'SEP'; } <<EOF>> { return 'EOF'; } /lex %right LAMBDA %left SEP %% file : expr EOF { return $expr; } ; expr : LAMBDA var_list '.' expr %{ var temp = ["LambdaExpr", $var_list.shift(), $expr]; $var_list.forEach(function (v) { temp = ["LambdaExpr", v, temp]; }); $ = temp; %} | expr SEP expr { $ = ["ApplyExpr", $expr1, $expr2]; } | var { $ = ["VarExpr", $var]; } | '(' expr ')' { $ = $expr; } ; var_list : var_list var { $ = $var_list; $.unshift($var); } | var { $ = [$var]; } ; var : VAR { $ = yytext; } ; ` let prec = ` %lex %% \s+ {/* skip whitespace */} [0-9]+ {return 'NAT';} "+" {return '+';} "*" {return '*';} <<EOF>> {return 'EOF';} /lex %left '+' %left '*' %% S : e EOF {return $1;} ; e : e '+' e {$ = [$1,'+', $3];} | e '*' e {$ = [$1, '*', $3];} | NAT {$ = parseInt(yytext);} ; ` module.exports = { lambda, prec, basic, calc, classy }
  • typal - /jison/typal
    Last edited 5 years ago
    /* * Introduces a typal object to make classical/prototypal patterns easier * Plus some AOP sugar * * By Zachary Carter <zach@carter.name> * MIT Licensed * */ var typal = (function () { var create = Object.create || function (o) { function F(){} F.prototype = o; return new F(); }; var position = /^(before|after)/; // basic method layering // always returns original method's return value function layerMethod(k, fun) { var pos = k.match(position)[0], key = k.replace(position, ''), prop = this[key]; if (pos === 'after') { this[key] = function () { var ret = prop.apply(this, arguments); var args = [].slice.call(arguments); args.splice(0, 0, ret); fun.apply(this, args); return ret; }; } else if (pos === 'before') { this[key] = function () { fun.apply(this, arguments); var ret = prop.apply(this, arguments); return ret; }; } } // mixes each argument's own properties into calling object, // overwriting them or layering them. i.e. an object method 'meth' is // layered by mixin methods 'beforemeth' or 'aftermeth' function typal_mix() { var self = this; for(var i=0,o,k; i<arguments.length; i++) { o=arguments[i]; if (!o) continue; if (Object.prototype.hasOwnProperty.call(o,'constructor')) this.constructor = o.constructor; if (Object.prototype.hasOwnProperty.call(o,'toString')) this.toString = o.toString; for(k in o) { if (Object.prototype.hasOwnProperty.call(o, k)) { if(k.match(position) && typeof this[k.replace(position, '')] === 'function') layerMethod.call(this, k, o[k]); else this[k] = o[k]; } } } return this; } return { // extend object with own typalperties of each argument mix: typal_mix, // sugar for object begetting and mixing // - Object.create(typal).mix(etc, etc); // + typal.beget(etc, etc); beget: function typal_beget() { return arguments.length ? typal_mix.apply(create(this), arguments) : create(this); }, // Creates a new Class function based on an object with a constructor method construct: function typal_construct() { var o = typal_mix.apply(create(this), arguments); var constructor = o.constructor; var Klass = o.constructor = function () { return constructor.apply(this, arguments); }; Klass.prototype = o; Klass.mix = typal_mix; // allow for easy singleton property extension return Klass; }, // no op constructor: function typal_constructor() { return this; } }; })(); module.exports = typal;