From e72e20e025ab14320c79c2dca75721a0a5e002bd Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 12 Sep 2026 01:35:30 +0200 Subject: Allow random text after ending the module --- boot/lexer.ll | 15 ++++++++++++++- boot/parser.yy | 6 ++++++ include/elna/boot/driver.h | 3 +++ testsuite/compilable/trailing_text.elna | 4 ++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 testsuite/compilable/trailing_text.elna diff --git a/boot/lexer.ll b/boot/lexer.ll index e8dde7c..89eb4ed 100644 --- a/boot/lexer.ll +++ b/boot/lexer.ll @@ -55,6 +55,10 @@ EXPONENT [eE][+-]?[[:digit:]]+ %% %{ + if (driver.finished) + { + return yy::parser::make_YYEOF(this->location); + } this->location.step(); %} @@ -65,8 +69,17 @@ EXPONENT [eE][+-]?[[:digit:]]+ \n+ { this->location.step(); } + <> { + driver.add_error("Unterminated comment", this->comment_start); + BEGIN(INITIAL); + + return yy::parser::make_YYEOF(this->location); + } +} +\(\* { + this->comment_start = this->location; + BEGIN(IN_COMMENT); } -\(\* BEGIN(IN_COMMENT); [ \t\r] { this->location.step(); } diff --git a/boot/parser.yy b/boot/parser.yy index cc0a46c..f97d545 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -45,6 +45,8 @@ along with GCC; see the file COPYING3. If not see { public: yy::location location; + /// Where the comment being scanned was opened. + yy::location comment_start; lexer(std::istream& arg_yyin) : yyFlexLexer(&arg_yyin) @@ -167,12 +169,16 @@ along with GCC; see the file COPYING3. If not see program: import_part type_part variable_part procedure_part "end" "." { + driver.finished = true; + boot::unit *tree = new boot::unit(boot::make_position(@$), $1, $2, $3, $4); driver.tree.reset(tree); } | import_part type_part variable_part procedure_part "program" "(" optional_identifiers ")" procedure_body "end" "." { + driver.finished = true; + boot::unit *tree = new boot::unit(boot::make_position(@$), $1, $2, $3, $4, std::move($7), boot::make_position(@5), std::move(*$9)); driver.tree.reset(tree); diff --git a/include/elna/boot/driver.h b/include/elna/boot/driver.h index 45e2e40..e918954 100644 --- a/include/elna/boot/driver.h +++ b/include/elna/boot/driver.h @@ -39,6 +39,9 @@ namespace elna::boot { public: std::unique_ptr tree; + /// Set once the module terminator has been parsed. The lexer stops + /// scanning then, so whatever follows is not program text. + bool finished{ false }; driver() = default; }; diff --git a/testsuite/compilable/trailing_text.elna b/testsuite/compilable/trailing_text.elna new file mode 100644 index 0000000..1eb3595 --- /dev/null +++ b/testsuite/compilable/trailing_text.elna @@ -0,0 +1,4 @@ +end. + +Everything after the module terminator is ignored and is never scanned, so it +does not have to be Elna: proc 1 2 3 "unterminated -- cgit v1.2.3