Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add web workers, parse automatically #272

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ node_modules
# Editor backup files
*.bak
*~
web/content/assets/js/jison.js
web/content/assets/js/jison.js
web/crash.log
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nanoc kept creating this file for some reason ^

133 changes: 101 additions & 32 deletions web/content/assets/js/try.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
(function ($) {

var worker = new Worker('../assets/js/worker.js');

var parser,
parser2;

Expand All @@ -13,8 +15,20 @@ print = function (){}

var printOut = function (str) { $("#out").html(str); };

function debounce(timeout, fn) {
var timer;

return function() {
clearTimeout(timer);

timer = setTimeout(function() {
fn();
timer = null;
}, timeout);
};
}

$(document).ready(function () {
$("#process_btn").click(processGrammar);
$("#parse_btn").click(runParser);

$("#examples").change(function(ev) {
Expand All @@ -23,52 +37,107 @@ $(document).ready(function () {
$.get("/jison/examples/"+file, function (data) {
$("#grammar").val(data);
$(document.body).removeClass("loading");
processGrammar();
});
});


// recompile the grammar using a web worker,
// as the user types
var onChange = debounce(700, processGrammar);
$('#grammar').bind('input propertychange', onChange);
processGrammar();
});

function processGrammar () {
var type = "lalr";

var grammar = $("#grammar").val();
try {
var cfg = JSON.parse(grammar);
} catch(e) {

function onError(e) {
console.log(e);
$("#gen_out").html("Oops. Make sure your grammar is " +
"in the correct format."+ "\n" + e.stack)
.removeClass('good')
.removeClass('warning')
.addClass('bad');
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not strictly related to the web worker stuff, but I thought it would be nice if it printed out a full stack trace. More info is helpful. :)


function onSuccess(result) {

try {
var cfg = bnf.parse(grammar);
parser = Jison.Generator(result.cfg, {type: result.type});
} catch (e) {
$("#gen_out").html("Oops. Make sure your grammar is in the correct format.\n"+e).addClass('bad');
return;
return onError(e);
}

$("#out").removeClass("good").removeClass("bad").html('');
$("#gen_out").removeClass("good").removeClass("bad").removeClass('warning');
if (!parser.conflicts) {
$("#gen_out").html('Generated successfully!').addClass('good');
} else {
$("#gen_out").html('Conflicts encountered:<br/>').addClass('bad');
}
}

Jison.print = function () {};
parser = Jison.Generator(cfg, {type: type});
$("#download_btn").click(function () {
window.location.href = "data:application/javascript;charset=utf-8;base64,"+Base64.encode(parser.generate());
}).removeAttr('disabled');



parser.resolutions.forEach(function (res) {
var r = res[2];
if (!r.bydefault) return;
$("#gen_out").append(r.msg+"\n"+"("+r.s+", "+r.r+") -> "+r.action);
});

parser2 = parser.createParser();
}

// for newer browsers
function callWorker(grammar) {
worker.addEventListener('error', onError);
worker.addEventListener('message', function(e) {
onSuccess(e.data.result);
});

// ask the web worker to parse the grammar for us
worker.postMessage(grammar);
}

// for older browsers (IE <=9, Android <=4.3)
function callNonWorker(grammar) {
Jison.print = function () {};
var cfg;

$("#out").removeClass("good").removeClass("bad").html('');
$("#gen_out").removeClass("good").removeClass("bad");
if (!parser.conflicts) {
$("#gen_out").html('Generated successfully!').addClass('good');
try {
cfg = JSON.parse(grammar);
} catch (e) {
try {
cfg = bnf.parse(grammar);
} catch (e) {
return onError(e);
}
}

onSuccess({cfg: cfg, type: 'lalr'});
}

$("#gen_out").html("Parsing...")
.removeClass('good')
.removeClass('bad')
.addClass('warning');
$('#download_btn').attr('disabled', true);

var grammar = $("#grammar").val();

if (typeof Worker !== 'undefined') {
callWorker(grammar);
} else {
$("#gen_out").html('Conflicts encountered:<br/>').addClass('bad');
callNonWorker(grammar);
}

$("#download_btn").click(function () {
window.location.href = "data:application/javascript;charset=utf-8;base64,"+Base64.encode(parser.generate());
}).removeAttr('disabled');

parser.resolutions.forEach(function (res) {
var r = res[2];
if (!r.bydefault) return;
$("#gen_out").append(r.msg+"\n"+"("+r.s+", "+r.r+") -> "+r.action);
});

parser2 = parser.createParser();
}

function runParser () {
if (!parser) processGrammar();
if (!parser) {
processGrammar();
}
printOut("Parsing...");
var source = $("#source").val();
try {
Expand Down
24 changes: 24 additions & 0 deletions web/content/assets/js/worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

importScripts('jison.js');
Jison.print = function () {};

// request to parse a grammar
self.addEventListener('message', function (e) {
if (typeof e.data !== 'string') {
return;
}

var grammar = e.data;

var cfg;

try {
cfg = JSON.parse(grammar);
} catch (e) {
// intentionally throw an error here if it fails to parse
cfg = bnf.parse(grammar);
}

self.postMessage({result: {cfg: cfg, type: "lalr"}});
});
5 changes: 5 additions & 0 deletions web/content/assets/styles/try.css
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,8 @@ table tr:hover td {
background: #fee;
border: 2px solid red;
}

.warning {
background: #feffef;
border: 2px solid yellow;
}
1 change: 0 additions & 1 deletion web/content/try.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ <h2>Describe Your Language</h2>
;
</textarea>
<p>
<button id="process_btn">Generate Parser</button>
<button id="download_btn" disabled>Download</button>
</p>
<pre id="gen_out"></pre>
Expand Down