From 9cf3a93b70e56b789a38e5218dade68934a632ce Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 11:47:24 +0200 Subject: [PATCH] fix parseInludes bug --- .../ReducerProject_IncludeParser.js | 328 +++++++----------- .../ReducerProject_IncludeParser.peggy | 5 +- .../ReducerProject_ParseIncludes.res | 13 +- .../ReducerProject_ProjectItem.res | 2 +- 4 files changed, 145 insertions(+), 203 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js index cb8c66eb..e04b8ba2 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js @@ -5,9 +5,7 @@ "use strict"; function peg$subclass(child, parent) { - function C() { - this.constructor = child; - } + function C() { this.constructor = child; } C.prototype = parent.prototype; child.prototype = new C(); } @@ -29,15 +27,13 @@ peg$subclass(peg$SyntaxError, Error); function peg$padEnd(str, targetLength, padString) { padString = padString || " "; - if (str.length > targetLength) { - return str; - } + if (str.length > targetLength) { return str; } targetLength -= str.length; padString += padString.repeat(targetLength); return str + padString.slice(0, targetLength); } -peg$SyntaxError.prototype.format = function (sources) { +peg$SyntaxError.prototype.format = function(sources) { var str = "Error: " + this.message; if (this.location) { var src = null; @@ -52,24 +48,15 @@ peg$SyntaxError.prototype.format = function (sources) { var loc = this.location.source + ":" + s.line + ":" + s.column; if (src) { var e = this.location.end; - var filler = peg$padEnd("", s.line.toString().length, " "); + var filler = peg$padEnd("", s.line.toString().length, ' '); var line = src[s.line - 1]; var last = s.line === e.line ? e.column : line.length + 1; - var hatLen = last - s.column || 1; - str += - "\n --> " + - loc + - "\n" + - filler + - " |\n" + - s.line + - " | " + - line + - "\n" + - filler + - " | " + - peg$padEnd("", s.column - 1, " ") + - peg$padEnd("", hatLen, "^"); + var hatLen = (last - s.column) || 1; + str += "\n --> " + loc + "\n" + + filler + " |\n" + + s.line + " | " + line + "\n" + + filler + " | " + peg$padEnd("", s.column - 1, ' ') + + peg$padEnd("", hatLen, "^"); } else { str += "\n at " + loc; } @@ -77,35 +64,33 @@ peg$SyntaxError.prototype.format = function (sources) { return str; }; -peg$SyntaxError.buildMessage = function (expected, found) { +peg$SyntaxError.buildMessage = function(expected, found) { var DESCRIBE_EXPECTATION_FNS = { - literal: function (expectation) { - return '"' + literalEscape(expectation.text) + '"'; + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; }, - class: function (expectation) { - var escapedParts = expectation.parts.map(function (part) { + class: function(expectation) { + var escapedParts = expectation.parts.map(function(part) { return Array.isArray(part) ? classEscape(part[0]) + "-" + classEscape(part[1]) : classEscape(part); }); - return ( - "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]" - ); + return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]"; }, - any: function () { + any: function() { return "any character"; }, - end: function () { + end: function() { return "end of input"; }, - other: function (expectation) { + other: function(expectation) { return expectation.description; - }, + } }; function hex(ch) { @@ -115,17 +100,13 @@ peg$SyntaxError.buildMessage = function (expected, found) { function literalEscape(s) { return s .replace(/\\/g, "\\\\") - .replace(/"/g, '\\"') + .replace(/"/g, "\\\"") .replace(/\0/g, "\\0") .replace(/\t/g, "\\t") .replace(/\n/g, "\\n") .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, function (ch) { - return "\\x0" + hex(ch); - }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) { - return "\\x" + hex(ch); - }); + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); } function classEscape(s) { @@ -133,17 +114,13 @@ peg$SyntaxError.buildMessage = function (expected, found) { .replace(/\\/g, "\\\\") .replace(/\]/g, "\\]") .replace(/\^/g, "\\^") - .replace(/-/g, "\\-") + .replace(/-/g, "\\-") .replace(/\0/g, "\\0") .replace(/\t/g, "\\t") .replace(/\n/g, "\\n") .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, function (ch) { - return "\\x0" + hex(ch); - }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) { - return "\\x" + hex(ch); - }); + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); } function describeExpectation(expectation) { @@ -174,25 +151,17 @@ peg$SyntaxError.buildMessage = function (expected, found) { return descriptions[0] + " or " + descriptions[1]; default: - return ( - descriptions.slice(0, -1).join(", ") + - ", or " + - descriptions[descriptions.length - 1] - ); + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; } } function describeFound(found) { - return found ? '"' + literalEscape(found) + '"' : "end of input"; + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; } - return ( - "Expected " + - describeExpected(expected) + - " but " + - describeFound(found) + - " found." - ); + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; }; function peg$parse(input, options) { @@ -206,7 +175,7 @@ function peg$parse(input, options) { var peg$c0 = "#include"; var peg$c1 = "'"; - var peg$c2 = '"'; + var peg$c2 = "\""; var peg$c3 = "//"; var peg$c4 = "/*"; var peg$c5 = "*/"; @@ -222,8 +191,8 @@ function peg$parse(input, options) { var peg$e1 = peg$otherExpectation("string"); var peg$e2 = peg$literalExpectation("'", false); var peg$e3 = peg$classExpectation(["'"], true, false); - var peg$e4 = peg$literalExpectation('"', false); - var peg$e5 = peg$classExpectation(['"'], true, false); + var peg$e4 = peg$literalExpectation("\"", false); + var peg$e5 = peg$classExpectation(["\""], true, false); var peg$e6 = peg$literalExpectation("//", false); var peg$e7 = peg$literalExpectation("/*", false); var peg$e8 = peg$classExpectation(["*"], true, false); @@ -234,24 +203,12 @@ function peg$parse(input, options) { var peg$e13 = peg$classExpectation(["\n", "\r"], false, false); var peg$e14 = peg$classExpectation(["\r", "\n"], true, false); - var peg$f0 = function (head, tail) { - return [head, ...tail].filter((e) => e != ""); - }; - var peg$f1 = function () { - return []; - }; - var peg$f2 = function (characters) { - return characters.join(""); - }; - var peg$f3 = function (characters) { - return characters.join(""); - }; - var peg$f4 = function () { - return ""; - }; - var peg$f5 = function () { - return ""; - }; + var peg$f0 = function(head, tail) {return [head, ...tail].filter( e => e != '');}; + var peg$f1 = function() {return [];}; + var peg$f2 = function(characters) {return characters.join('');}; + var peg$f3 = function(characters) {return characters.join('');}; + var peg$f4 = function() { return '';}; + var peg$f5 = function() { return '';}; var peg$currPos = 0; var peg$savedPos = 0; var peg$posDetailsCache = [{ line: 1, column: 1 }]; @@ -265,9 +222,7 @@ function peg$parse(input, options) { if ("startRule" in options) { if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error( - "Can't start parsing from rule \"" + options.startRule + '".' - ); + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); } peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; @@ -285,7 +240,7 @@ function peg$parse(input, options) { return { source: peg$source, start: peg$savedPos, - end: peg$currPos, + end: peg$currPos }; } @@ -294,10 +249,9 @@ function peg$parse(input, options) { } function expected(description, location) { - location = - location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); throw peg$buildStructuredError( [peg$otherExpectation(description)], @@ -307,10 +261,9 @@ function peg$parse(input, options) { } function error(message, location) { - location = - location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); throw peg$buildSimpleError(message, location); } @@ -320,12 +273,7 @@ function peg$parse(input, options) { } function peg$classExpectation(parts, inverted, ignoreCase) { - return { - type: "class", - parts: parts, - inverted: inverted, - ignoreCase: ignoreCase, - }; + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; } function peg$anyExpectation() { @@ -355,7 +303,7 @@ function peg$parse(input, options) { details = peg$posDetailsCache[p]; details = { line: details.line, - column: details.column, + column: details.column }; while (p < pos) { @@ -384,20 +332,18 @@ function peg$parse(input, options) { start: { offset: startPos, line: startPosDetails.line, - column: startPosDetails.column, + column: startPosDetails.column }, end: { offset: endPos, line: endPosDetails.line, - column: endPosDetails.column, - }, + column: endPosDetails.column + } }; } function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { - return; - } + if (peg$currPos < peg$maxFailPos) { return; } if (peg$currPos > peg$maxFailPos) { peg$maxFailPos = peg$currPos; @@ -421,7 +367,7 @@ function peg$parse(input, options) { } function peg$parsestart() { - var s0, s1, s2, s3; + var s0, s1, s2, s3, s4; var key = peg$currPos * 10 + 0; var cached = peg$resultsCache[key]; @@ -433,16 +379,40 @@ function peg$parse(input, options) { } s0 = peg$currPos; - s1 = peg$parseincludes(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$parsenewLine(); - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$parsenewLine(); + s1 = []; + s2 = peg$parsenewLine(); + if (s2 === peg$FAILED) { + s2 = peg$parse_(); + if (s2 === peg$FAILED) { + s2 = peg$parsecomment(); + if (s2 === peg$FAILED) { + s2 = peg$parsedelimitedComment(); + } } - s3 = peg$parseignore(); - s0 = s1; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$parsenewLine(); + if (s2 === peg$FAILED) { + s2 = peg$parse_(); + if (s2 === peg$FAILED) { + s2 = peg$parsecomment(); + if (s2 === peg$FAILED) { + s2 = peg$parsedelimitedComment(); + } + } + } + } + s2 = peg$parseincludes(); + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$parsenewLine(); + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$parsenewLine(); + } + s4 = peg$parseignore(); + s0 = s2; } else { peg$currPos = s0; s0 = peg$FAILED; @@ -538,7 +508,7 @@ function peg$parse(input, options) { } function peg$parseincludeStatement() { - var s0, s1, s2, s3, s4, s5; + var s0, s1, s2, s3, s4, s5, s6; var key = peg$currPos * 10 + 2; var cached = peg$resultsCache[key]; @@ -550,31 +520,35 @@ function peg$parse(input, options) { } s0 = peg$currPos; + s1 = []; + s2 = peg$parse_(); + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$parse_(); + } if (input.substr(peg$currPos, 8) === peg$c0) { - s1 = peg$c0; + s2 = peg$c0; peg$currPos += 8; } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e0); - } + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$parse_(); - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$parse_(); + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$parse_(); } - s3 = peg$parsestring(); - if (s3 !== peg$FAILED) { - s4 = []; - s5 = peg$parse_(); - while (s5 !== peg$FAILED) { - s4.push(s5); - s5 = peg$parse_(); + s4 = peg$parsestring(); + if (s4 !== peg$FAILED) { + s5 = []; + s6 = peg$parse_(); + while (s6 !== peg$FAILED) { + s5.push(s6); + s6 = peg$parse_(); } - s0 = s3; + s0 = s4; } else { peg$currPos = s0; s0 = peg$FAILED; @@ -615,9 +589,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e2); - } + if (peg$silentFails === 0) { peg$fail(peg$e2); } } if (s2 !== peg$FAILED) { s3 = []; @@ -626,9 +598,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e3); - } + if (peg$silentFails === 0) { peg$fail(peg$e3); } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -637,9 +607,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e3); - } + if (peg$silentFails === 0) { peg$fail(peg$e3); } } } if (input.charCodeAt(peg$currPos) === 39) { @@ -647,9 +615,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e2); - } + if (peg$silentFails === 0) { peg$fail(peg$e2); } } if (s4 !== peg$FAILED) { s1 = s3; @@ -674,9 +640,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e4); - } + if (peg$silentFails === 0) { peg$fail(peg$e4); } } if (s2 !== peg$FAILED) { s3 = []; @@ -685,9 +649,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e5); - } + if (peg$silentFails === 0) { peg$fail(peg$e5); } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -696,9 +658,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e5); - } + if (peg$silentFails === 0) { peg$fail(peg$e5); } } } if (input.charCodeAt(peg$currPos) === 34) { @@ -706,9 +666,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e4); - } + if (peg$silentFails === 0) { peg$fail(peg$e4); } } if (s4 !== peg$FAILED) { s1 = s3; @@ -729,9 +687,7 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e1); - } + if (peg$silentFails === 0) { peg$fail(peg$e1); } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -793,9 +749,7 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e6); - } + if (peg$silentFails === 0) { peg$fail(peg$e6); } } if (s1 !== peg$FAILED) { s2 = []; @@ -834,9 +788,7 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e7); - } + if (peg$silentFails === 0) { peg$fail(peg$e7); } } if (s1 !== peg$FAILED) { s2 = []; @@ -845,9 +797,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e8); - } + if (peg$silentFails === 0) { peg$fail(peg$e8); } } while (s3 !== peg$FAILED) { s2.push(s3); @@ -856,9 +806,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e8); - } + if (peg$silentFails === 0) { peg$fail(peg$e8); } } } if (input.substr(peg$currPos, 2) === peg$c5) { @@ -866,9 +814,7 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e9); - } + if (peg$silentFails === 0) { peg$fail(peg$e9); } } if (s3 !== peg$FAILED) { peg$savedPos = s0; @@ -905,16 +851,12 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e11); - } + if (peg$silentFails === 0) { peg$fail(peg$e11); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e10); - } + if (peg$silentFails === 0) { peg$fail(peg$e10); } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -940,16 +882,12 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e13); - } + if (peg$silentFails === 0) { peg$fail(peg$e13); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e12); - } + if (peg$silentFails === 0) { peg$fail(peg$e12); } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -974,9 +912,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e14); - } + if (peg$silentFails === 0) { peg$fail(peg$e14); } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -1005,5 +941,5 @@ function peg$parse(input, options) { module.exports = { SyntaxError: peg$SyntaxError, - parse: peg$parse, + parse: peg$parse }; diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy index 25d69b93..dc65fac4 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy @@ -3,9 +3,8 @@ // #include "string" // #include "string2" - start - = @includes newLine* ignore + = (newLine/_/comment/delimitedComment)* @includes newLine* ignore includes = head:includeStatement tail:(newLine+ @includeStatement)* @@ -14,7 +13,7 @@ includes {return [];} includeStatement - = '#include' _* @string _* + = _* '#include' _* @string _* / comment / delimitedComment diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res index 347234a4..f6b17901 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res @@ -1,8 +1,15 @@ @module("./ReducerProject_IncludeParser.js") external parse__: string => array = "parse" -let parseIncludes = (expr: string): array => +let parseIncludes = (expr: string): result, Reducer_ErrorValue.errorValue> => try { - parse__(expr) + let answer = parse__(expr) + // let logEntry = answer->Js.Array2.joinWith(",") + // `parseIncludes: ${logEntry} for expr: ${expr}`->Js.log + answer->Ok } catch { - | Js.Exn.Error(_obj) => [] + | Js.Exn.Error(obj) => + RESyntaxError( + Belt.Option.getExn(Js.Exn.message(obj)), + Reducer_Peggy_Parse.syntaxErrorToLocation(obj)->Some, + )->Error } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index 047937f1..2608e344 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -106,7 +106,7 @@ let setIncludes = (T.ProjectItem(r): t, includes: T.includesType): t => T.Projec //TODO: forward parse errors to the user let parseIncludes = (this: t): t => - setIncludes(this, getSource(this)->ReducerProject_ParseIncludes.parseIncludes->Ok) + setIncludes(this, getSource(this)->ReducerProject_ParseIncludes.parseIncludes) let doRawParse = (this: t): T.rawParseArgumentType => this->getSource->Reducer_Peggy_Parse.parse