From 0d469abffc833698e2d9249a5ca1306dba5ecc01 Mon Sep 17 00:00:00 2001 From: Tangent Wantwight Date: Fri, 4 Aug 2023 15:19:36 -0400 Subject: [PATCH] Rearrange grammar to report text-after-closing-brace errors --- notcl.js | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/notcl.js b/notcl.js index a7ed44f..38ee7fb 100644 --- a/notcl.js +++ b/notcl.js @@ -14,12 +14,13 @@ var Notcl = (() => { const PreCommand = AtLeast(0, Choose(InterCommandWhitespace, Comment)); - const PreWordWhitespace = Regex(/[^\S\n;]*/y); + const PreWordWhitespace = Regex(/[^\S\n;]+/y).expects("whitespace"); - const BasicWord = Regex(/[^\s;]+/y).map(([word]) => ({ text: word })); + const BasicWord = Regex(/(?!\{)[^\s;]+/y) + .map(([word]) => ({ text: word })) + .expects("BASIC_WORD"); // WIP, need to be able to escape braces correctly - // WIP, error if anything after closing brace /** @type {Peg.Pattern} */ const Brace = Sequence( @@ -33,29 +34,35 @@ var Notcl = (() => { ), Regex(/\}/y).expects("}") ).map(([_left, fragments, _right]) => fragments.join("")); - - const Word = Sequence( - PreWordWhitespace, - Choose( - Brace.map((text) => ({ text })), - BasicWord - ) - ).map(([_padding, word]) => word); - - const CommandTerminator = Sequence( - PreWordWhitespace, - Choose(/** @type {Peg.Pattern} */ (Regex(/[\n;]/y)), End()) + const Word = Choose( + Brace.map((text) => ({ text })), + BasicWord ); + const CommandTerminator = Choose( + /** @type {Peg.Pattern} */ (Regex(/[\n;]/y)).expects( + "NEWLINE | ;" + ), + End() + ); /** @type {Peg.Pattern} */ - const Command = Sequence(PreCommand, AtLeast(0, Word), CommandTerminator).map( - ([_padding, words, _end]) => words - ); + const Command = Choose( + CommandTerminator.map(() => []), + Sequence( + Word, + AtLeast( + 0, + Sequence(PreWordWhitespace, Word).map(([_padding, word]) => word) + ), + Choose(Sequence(PreWordWhitespace, Word), CommandTerminator) + ).map(([word, moreWords, _end]) => [word].concat(moreWords)) + ).expects("COMMAND"); /** @type {Peg.Pattern} */ - const Script = Sequence(AtLeast(0, Command), End()).map( - ([commands, _eof]) => commands - ); + const Script = Sequence( + AtLeast(0, Sequence(PreCommand, Command)), + Choose(End(), Sequence(PreCommand, Command)) + ).map(([commands, _eof]) => commands.map(([_padding, command]) => command)); const ERROR_CONTEXT = /(?<=([^\n]{0,50}))([^\n]{0,50})/y;