diff --git a/hmmlib-js/hmmlib.js b/hmmlib-js/hmmlib.js index 7d48834..722fe2e 100644 --- a/hmmlib-js/hmmlib.js +++ b/hmmlib-js/hmmlib.js @@ -37,10 +37,6 @@ function HMML_parse(contents) { isbn: "", offset: 0 }, - error: { - line: 0, - msg: "" - }, attr: "", mnext: 0, first: true @@ -65,7 +61,7 @@ function HMML_parse(contents) { }; } catch (e) { return { - error: state.error + error: e }; } } @@ -397,14 +393,15 @@ HMMLexer.prototype = { }, performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { function ERR(yy, err) { - console.log(err); - yy.error.line = yy.line; - yy.error.msg = err; - throw "tantrum"; + console.log("hmmlib error: L%d: %s\n", yy.line, err); + throw { + message: err, + line: yy.line + }; } function CHECKESCAPE(yy, str) { - if (!"[]:@~\\\"".find(str)) { + if ("[]:@~\\\"".indexOf(str) == -1) { ERR(yy, "hmmlib: Unknown backslash escape code: %s", str); } } @@ -530,285 +527,289 @@ HMMLexer.prototype = { yy_.begin("VIDEO"); break; case 18: + NEWANNO(yy); + return 1; + break; + case 19: NEWANNO(yy); yy.an.time = yy_.yytext.substr(1, yy_.yyleng - 4); yy_.begin("AUTHOR"); break; - case 19: + case 20: NEWANNO(yy); yy.an.time = yy_.yytext.substr(1, yy_.yyleng - 2); yy_.begin("TEXT_START"); break; - case 20: + case 21: ERR(yy, "Timecode '" + yy_.yytext + "' out of range."); break; - case 21: - break; case 22: - ERR(yy, "Cannot parse annotation. Expected timecode."); break; case 23: - M_(yy, "CATEGORY", "TEXT"); - yy_.begin("MARKER"); + ERR(yy, "Cannot parse annotation. Expected timecode."); break; case 24: - M_(yy, "MEMBER", "TEXT"); + M_(yy, "CATEGORY", "TEXT"); yy_.begin("MARKER"); break; case 25: - M_(yy, "PROJECT", "TEXT"); + M_(yy, "MEMBER", "TEXT"); yy_.begin("MARKER"); break; case 26: + M_(yy, "PROJECT", "TEXT"); + yy_.begin("MARKER"); + break; + case 27: yy_.less(0); yy_.begin("TEXT"); break; - case 27: + case 28: ERR(yy, "Unknown character '" + yy_.yytext + "' after timecode."); break; - case 28: + case 29: yy.an.text += yy_.yytext; break; - case 29: + case 30: CHECKESCAPE(yy, yy_.yytext.charAt(1)); yy.an.text += yy_.yytext.substr(1, yy_.yyleng - 1); break; - case 30: - yy.an.text += ' '; - M_(yy, "CATEGORY", "TEXT"); - yy_.begin("MARKER"); - break; case 31: yy.an.text += ' '; - M_(yy, "MEMBER", "TEXT"); + M_(yy, "CATEGORY", "TEXT"); yy_.begin("MARKER"); break; case 32: yy.an.text += ' '; - M_(yy, "PROJECT", "TEXT"); + M_(yy, "MEMBER", "TEXT"); yy_.begin("MARKER"); break; case 33: - M_(yy, "CATEGORY", "MARKER_XTRA"); + yy.an.text += ' '; + M_(yy, "PROJECT", "TEXT"); yy_.begin("MARKER"); break; case 34: - M_(yy, "MEMBER", "MARKER_XTRA"); + M_(yy, "CATEGORY", "MARKER_XTRA"); yy_.begin("MARKER"); break; case 35: - M_(yy, "PROJECT", "MARKER_XTRA"); + M_(yy, "MEMBER", "MARKER_XTRA"); yy_.begin("MARKER"); break; case 36: - yy_.begin("AFTERTEXT"); + M_(yy, "PROJECT", "MARKER_XTRA"); + yy_.begin("MARKER"); break; case 37: + yy_.begin("AFTERTEXT"); + break; + case 38: yy.ref.offset = yy.an.text.length; yy_.begin("REF"); break; - case 38: - break; case 39: - yy.an.text += ' '; break; case 40: - yy.an.text += yy_.yytext; + yy.an.text += ' '; break; case 41: + yy.an.text += yy_.yytext; + break; + case 42: M_ADD(yy, yy_.yytext); yy_.begin(yy.mnext); break; - case 42: + case 43: M_ADD(yy, yy_.yytext.substr(1, yy_.yyleng - 2)); yy_.begin(yy.mnext); break; - case 43: + case 44: ERR(yy, "Cannot parse Marker. Expected quoted or alphanumeric attribute."); break; - case 44: + case 45: MX_ADD(yy, ']'); break; - case 45: + case 46: yy_.begin("TEXT"); break; - case 46: + case 47: if (yy.an.markers[yy.an.markers.length - 1].parameter) { MX_ADD(yy, ' '); } break; - case 47: + case 48: MX_ADD(yy, yy_.yytext); break; - case 48: - break; case 49: + break; + case 50: yy.attr = "site"; yy_.begin("R_ATTR"); break; - case 50: + case 51: yy.attr = "page"; yy_.begin("R_ATTR"); break; - case 51: + case 52: yy.attr = "url"; yy_.begin("R_ATTR"); break; - case 52: + case 53: yy.attr = "title"; yy_.begin("R_ATTR"); break; - case 53: + case 54: yy.attr = "article"; yy_.begin("R_ATTR"); break; - case 54: + case 55: yy.attr = "author"; yy_.begin("R_ATTR"); break; - case 55: + case 56: yy.attr = "editor"; yy_.begin("R_ATTR"); break; - case 56: + case 57: yy.attr = "publisher"; yy_.begin("R_ATTR"); break; - case 57: + case 58: yy.attr = "isbn"; yy_.begin("R_ATTR"); break; - case 58: + case 59: yy.an.references.push(yy.ref); yy.ref = {}; yy_.begin("TEXT"); break; - case 59: + case 60: ERR(yy, "Unexpected item in ref: " + yy_.yytext); break; - case 60: - break; case 61: + break; + case 62: yy.ref[yy.attr] = yy_.yytext; yy_.begin("REF"); break; - case 62: + case 63: yy.ref[yy.attr] = UNQUOTE(yy, yy_.yytext.substr(1, yy_.yyleng - 2)); yy_.begin("REF"); break; - case 63: + case 64: NEWANNO(yy); return 1; break; - case 64: - break; case 65: - yy_.begin("QUOTES"); break; case 66: + yy_.begin("QUOTES"); + break; + case 67: yy_.begin("CATEGORIES"); yy_.less(1); break; - case 67: + case 68: yy_.begin("ANNOTATION"); yy_.less(0); break; - case 68: - ERR(yy, "Unexpected thing after text node: " + yy_.yytext); - break; case 69: ERR(yy, "Unexpected thing after text node: " + yy_.yytext); break; case 70: - yy.an.author = yy_.yytext.substr(0, yy_.yyleng - 1); - yy_.begin("TEXT_START"); + ERR(yy, "Unexpected thing after text node: " + yy_.yytext); break; case 71: + yy.an.author = yy_.yytext.substr(0, yy_.yyleng - 1); + yy_.begin("TEXT_START"); break; case 72: break; case 73: + break; + case 74: yy.an.markers.push({ type: "CATEGORY", marker: yy_.yytext.substr(1, yy_.yyleng - 1), offset: -1 }); break; - case 74: + case 75: yy.an.markers.push({ type: "CATEGORY", marker: UNQUOTE(yy, yy_.yytext.substr(2, yy_.yyleng - 3)), offset: -1 }); break; - case 75: + case 76: yy_.begin("QUOTES"); break; - case 76: + case 77: yy_.begin("ANNOTATION"); break; - case 77: + case 78: ERR(yy, "Unexpected character in category tag: " + yy_.yytext); break; - case 78: - break; case 79: + break; + case 80: yy.an.is_quote = true; yy.an.quote.id = parseInt(yy_.yytext); yy_.begin("ANNOTATION"); break; - case 80: + case 81: yy.an.quote.author += yy_.yytext; break; - case 81: + case 82: ERR(yy, "Unexpected character in quotes tag: " + yy_.yytext); break; } }, - rules: [/^(?:$)/, /^(?:\r\n|\n)/, /^(?:(\[video\b))/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:member([\t \r]*)=)/, /^(?:twitch_username([\t \r]*)=)/, /^(?:project([\t \r]*)=)/, /^(?:title([\t \r]*)=)/, /^(?:platform([\t \r]*)=)/, /^(?:id([\t \r]*)=)/, /^(?:annotator([\t \r]*)=)/, /^(?:\])/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:([^\" \]\t\r\n][^ \]\t\r\n]*))/, /^(?:("([^\n\"\\]|\\.)*"))/, /^(?:\])/, /^(?:(\[[0-9]{1,2}(:[0-5][0-9]){1,2}\])(\[)@)/, /^(?:(\[[0-9]{1,2}(:[0-5][0-9]){1,2}\]))/, /^(?:(\[[0-9]{1,2}(:[6-9][0-9]){1,2}\]))/, /^(?:([\t \r]+))/, /^(?:.)/, /^(?:(\[):)/, /^(?:(\[)@)/, /^(?:(\[)~)/, /^(?:(\[))/, /^(?:.)/, /^(?:([^\\\:\@\~\[\]\r\n\t ])+)/, /^(?:\\.)/, /^(?:[ \r\t]+:)/, /^(?:[ \r\t]+@)/, /^(?:[ \r\t]+~)/, /^(?:(\[):)/, /^(?:(\[)@)/, /^(?:(\[)~)/, /^(?:\])/, /^(?:(\[)ref\b)/, /^(?:(\[))/, /^(?:([\t \r]+))/, /^(?:.)/, /^(?:([0-9a-zA-Z][0-9a-zA-Z_]*))/, /^(?:("([^\n\"\\]|\\.)*"))/, /^(?:.)/, /^(?:\\)/, /^(?:\])/, /^(?:[ ])/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:site([\t \r]*)=)/, /^(?:page([\t \r]*)=)/, /^(?:url([\t \r]*)=)/, /^(?:title([\t \r]*)=)/, /^(?:article([\t \r]*)=)/, /^(?:author([\t \r]*)=)/, /^(?:editor([\t \r]*)=)/, /^(?:publisher([\t \r]*)=)/, /^(?:isbn([\t \r]*)=)/, /^(?:\])/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:([^\" \]\t\r\n][^ \]\t\r\n]*))/, /^(?:("([^\n\"\\]|\\.)*"))/, /^(?:\[\/video\])/, /^(?:([\t \r]+))/, /^(?:(\[)quote\b)/, /^(?:(\[):)/, /^(?:(\[)[0-9])/, /^(?:..)/, /^(?:.)/, /^(?:[^\]\n]+\])/, /^(?:([\t \r]+))/, /^(?:([\t \r]+))/, /^(?::([^\" \]\t\r\n][^ \]\t\r\n]*))/, /^(?::("([^\n\"\\]|\\.)*"))/, /^(?:\](\[))/, /^(?:\])/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:[0-9]+([\t \r]*)\])/, /^(?:([0-9a-zA-Z][0-9a-zA-Z_]*))/, /^(?:.)/], + rules: [/^(?:$)/, /^(?:\r\n|\n)/, /^(?:(\[video\b))/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:member([\t \r]*)=)/, /^(?:twitch_username([\t \r]*)=)/, /^(?:project([\t \r]*)=)/, /^(?:title([\t \r]*)=)/, /^(?:platform([\t \r]*)=)/, /^(?:id([\t \r]*)=)/, /^(?:annotator([\t \r]*)=)/, /^(?:\])/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:([^\" \]\t\r\n][^ \]\t\r\n]*))/, /^(?:("([^\n\"\\]|\\.)*"))/, /^(?:\])/, /^(?:\[\/video\])/, /^(?:(\[[0-9]{1,2}(:[0-5][0-9]){1,2}\])(\[)@)/, /^(?:(\[[0-9]{1,2}(:[0-5][0-9]){1,2}\]))/, /^(?:(\[[0-9]{1,2}(:[6-9][0-9]){1,2}\]))/, /^(?:([\t \r]+))/, /^(?:.)/, /^(?:(\[):)/, /^(?:(\[)@)/, /^(?:(\[)~)/, /^(?:(\[))/, /^(?:.)/, /^(?:([^\\\:\@\~\[\]\r\n\t ])+)/, /^(?:\\.)/, /^(?:[ \r\t]+:)/, /^(?:[ \r\t]+@)/, /^(?:[ \r\t]+~)/, /^(?:(\[):)/, /^(?:(\[)@)/, /^(?:(\[)~)/, /^(?:\])/, /^(?:(\[)ref\b)/, /^(?:(\[))/, /^(?:([\t \r]+))/, /^(?:.)/, /^(?:([0-9a-zA-Z][0-9a-zA-Z_]*))/, /^(?:("([^\n\"\\]|\\.)*"))/, /^(?:.)/, /^(?:\\)/, /^(?:\])/, /^(?:[ ])/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:site([\t \r]*)=)/, /^(?:page([\t \r]*)=)/, /^(?:url([\t \r]*)=)/, /^(?:title([\t \r]*)=)/, /^(?:article([\t \r]*)=)/, /^(?:author([\t \r]*)=)/, /^(?:editor([\t \r]*)=)/, /^(?:publisher([\t \r]*)=)/, /^(?:isbn([\t \r]*)=)/, /^(?:\])/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:([^\" \]\t\r\n][^ \]\t\r\n]*))/, /^(?:("([^\n\"\\]|\\.)*"))/, /^(?:\[\/video\])/, /^(?:([\t \r]+))/, /^(?:(\[)quote\b)/, /^(?:(\[):)/, /^(?:(\[)[0-9])/, /^(?:..)/, /^(?:.)/, /^(?:[^\]\n]+\])/, /^(?:([\t \r]+))/, /^(?:([\t \r]+))/, /^(?::([^\" \]\t\r\n][^ \]\t\r\n]*))/, /^(?::("([^\n\"\\]|\\.)*"))/, /^(?:\](\[))/, /^(?:\])/, /^(?:.)/, /^(?:([\t \r]+))/, /^(?:[0-9]+([\t \r]*)\])/, /^(?:([0-9a-zA-Z][0-9a-zA-Z_]*))/, /^(?:.)/], conditions: { "QUOTES": { - "rules": [0, 1, 78, 79, 80, 81], + "rules": [0, 1, 79, 80, 81, 82], "inclusive": true }, "CATEGORIES": { - "rules": [0, 1, 72, 73, 74, 75, 76, 77], + "rules": [0, 1, 73, 74, 75, 76, 77, 78], "inclusive": true }, "AUTHOR": { - "rules": [0, 1, 70, 71], + "rules": [0, 1, 71, 72], "inclusive": true }, "AFTERTEXT": { - "rules": [0, 1, 63, 64, 65, 66, 67, 68, 69], + "rules": [0, 1, 64, 65, 66, 67, 68, 69, 70], "inclusive": true }, "R_ATTR": { - "rules": [0, 1, 60, 61, 62], + "rules": [0, 1, 61, 62, 63], "inclusive": true }, "REF": { - "rules": [0, 1, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59], + "rules": [0, 1, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60], "inclusive": true }, "MARKER_XTRA": { - "rules": [0, 1, 44, 45, 46, 47], + "rules": [0, 1, 45, 46, 47, 48], "inclusive": true }, "MARKER": { - "rules": [0, 1, 41, 42, 43], + "rules": [0, 1, 42, 43, 44], "inclusive": true }, "TEXT": { - "rules": [0, 1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40], + "rules": [0, 1, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41], "inclusive": true }, "TEXT_START": { - "rules": [0, 1, 23, 24, 25, 26, 27], + "rules": [0, 1, 24, 25, 26, 27, 28], "inclusive": true }, "ANNOTATION": { - "rules": [0, 1, 18, 19, 20, 21, 22, 63], + "rules": [0, 1, 18, 19, 20, 21, 22, 23], "inclusive": true }, "V_ATTR": { diff --git a/hmmlib-js/src/header.js b/hmmlib-js/src/header.js index 7f427b9..6bffa7e 100644 --- a/hmmlib-js/src/header.js +++ b/hmmlib-js/src/header.js @@ -37,10 +37,6 @@ function HMML_parse(contents) { isbn: "", offset: 0 }, - error: { - line: 0, - msg: "" - }, attr: "", mnext: 0, first: true @@ -65,7 +61,7 @@ function HMML_parse(contents) { }; } catch (e) { return { - error: state.error + error: e }; } } diff --git a/hmmlib-js/src/source.l b/hmmlib-js/src/source.l index 7921b65..5a886cf 100644 --- a/hmmlib-js/src/source.l +++ b/hmmlib-js/src/source.l @@ -1,14 +1,12 @@ %{ function ERR(yy, err){ - console.log(err); - yy.error.line = yy.line; - yy.error.msg = err; - throw "tantrum"; + console.log("hmmlib error: L%d: %s\n", yy.line, err); + throw { message: err, line: yy.line }; } function CHECKESCAPE(yy, str){ - if(!"[]:@~\\\"".find(str)){ + if("[]:@~\\\"".indexOf(str) == -1){ ERR(yy, "hmmlib: Unknown backslash escape code: %s", str); } } @@ -120,11 +118,12 @@ RB \] {ATTR_QUOTED} { yy.meta[yy.attr] = UNQUOTE(yy, yytext.substr(1, yyleng-2)); yy_.begin("VIDEO"); } \] { yy_.less(0); yy_.begin("VIDEO"); } +\[\/video\] { NEWANNO(yy); return 1; } {TIMECODE}{LB}\@ { NEWANNO(yy); yy.an.time = yytext.substr(1, yyleng-4); yy_.begin("AUTHOR"); } -{TIMECODE} { NEWANNO(yy); yy.an.time = yytext.substr(1, yyleng-2); yy_.begin("TEXT_START"); } -{BAD_TIMECODE} { ERR(yy, "Timecode '"+ yytext +"' out of range."); } -{SP} {} -. { ERR(yy, "Cannot parse annotation. Expected timecode."); } +{TIMECODE} { NEWANNO(yy); yy.an.time = yytext.substr(1, yyleng-2); yy_.begin("TEXT_START"); } +{BAD_TIMECODE} { ERR(yy, "Timecode '"+ yytext +"' out of range."); } +{SP} {} +. { ERR(yy, "Cannot parse annotation. Expected timecode."); } {LB}\: { M_(yy, "CATEGORY", "TEXT"); yy_.begin("MARKER"); } {LB}\@ { M_(yy, "MEMBER" , "TEXT"); yy_.begin("MARKER"); } @@ -172,7 +171,7 @@ RB \] {ATTR_SIMPLE} { yy.ref[yy.attr] = yytext; yy_.begin("REF"); } {ATTR_QUOTED} { yy.ref[yy.attr] = UNQUOTE(yy, yytext.substr(1, yyleng-2)); yy_.begin("REF"); } -\[\/video\] { NEWANNO(yy); return 1; } +\[\/video\] { NEWANNO(yy); return 1; } {SP} {} {LB}quote { yy_.begin("QUOTES"); }