diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 3951e61e..84a58bcb 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -349,6 +349,7 @@ struct LexerState { bool atLineStart; uint32_t lineNo; uint32_t colNo; + int lastToken; struct IfStack *ifStack; @@ -372,6 +373,7 @@ static void initState(struct LexerState *state) { state->mode = LEXER_NORMAL; state->atLineStart = true; /* yylex() will init colNo due to this */ + state->lastToken = T_EOF; state->ifStack = NULL; @@ -2235,17 +2237,15 @@ finish: return T_STRING; lexer_SetMode(LEXER_NORMAL); - // If a macro is invoked on the last line of a file, with no blank - // line afterwards, returning EOF afterwards will cause Bison to - // stop parsing, despite the lexer being ready to output more. - // To avoid this, return T_NEWLINE for EOF as well. if (c == '\r' || c == '\n') { shiftChars(1); /* Handle CRLF */ if (c == '\r' && peek(0) == '\n') shiftChars(1); + return T_NEWLINE; } - return T_NEWLINE; + + return T_EOF; } #undef append_yylval_tzString @@ -2456,16 +2456,22 @@ restart: int token = lexerModeFuncs[lexerState->mode](); if (token == T_EOF) { - /* Try to switch to new buffer; if it succeeds, scan again */ - dbgPrint("Reached EOB!\n"); - /* Captures end at their buffer's boundary no matter what */ - if (!lexerState->capturing) { - if (!yywrap()) - goto restart; - dbgPrint("Reached end of input.\n"); - return T_EOF; + if (lexerState->lastToken != T_NEWLINE) { + dbgPrint("Forcing EOL at EOF\n"); + token = T_NEWLINE; + } else { + /* Try to switch to new buffer; if it succeeds, scan again */ + dbgPrint("Reached EOF!\n"); + /* Captures end at their buffer's boundary no matter what */ + if (!lexerState->capturing) { + if (!yywrap()) + goto restart; + dbgPrint("Reached end of input.\n"); + return T_EOF; + } } } + lexerState->lastToken = token; lexerState->atLineStart = token == T_NEWLINE; @@ -2524,6 +2530,7 @@ void lexer_CaptureRept(struct CaptureBody *capture) * We know we have read exactly "ENDR", not e.g. an EQUS */ lexerState->captureSize -= strlen("ENDR"); + lexerState->lastToken = T_POP_ENDR; // Force EOL at EOF goto finish; } level--; @@ -2586,6 +2593,7 @@ void lexer_CaptureMacroBody(struct CaptureBody *capture) * We know we have read exactly "ENDM", not e.g. an EQUS */ lexerState->captureSize -= strlen("ENDM"); + lexerState->lastToken = T_POP_ENDM; // Force EOL at EOF goto finish; } } diff --git a/src/asm/parser.y b/src/asm/parser.y index 0504ac17..c09a9dbd 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -603,20 +603,19 @@ enum { %% -asmfile : lines last_line +asmfile : lines ; +/* Note: The lexer adds T_NEWLINE at the end of the input */ lines : %empty | lines line ; -last_line : label - | label cpu_command - | label macro - | label directive - | assignment_directive -; -line : last_line T_NEWLINE +line : label T_NEWLINE + | label cpu_command T_NEWLINE + | label macro T_NEWLINE + | label directive T_NEWLINE + | assignment_directive T_NEWLINE | line_directive /* Directives that manage newlines themselves */ | error T_NEWLINE { /* Continue parsing the next line on a syntax error */ fstk_StopRept(); diff --git a/test/asm/block-comment-termination-error.err b/test/asm/block-comment-termination-error.err index e7641ede..f5e82102 100644 --- a/test/asm/block-comment-termination-error.err +++ b/test/asm/block-comment-termination-error.err @@ -1,5 +1,5 @@ ERROR: block-comment-termination-error.asm(1): Unterminated block comment ERROR: block-comment-termination-error.asm(1): - syntax error, unexpected end of file + syntax error, unexpected newline error: Assembly aborted (2 errors)! diff --git a/test/asm/code-after-endm-endr-endc.err b/test/asm/code-after-endm-endr-endc.err index c0db4313..65a7188f 100644 --- a/test/asm/code-after-endm-endr-endc.err +++ b/test/asm/code-after-endm-endr-endc.err @@ -7,9 +7,9 @@ ERROR: code-after-endm-endr-endc.asm(12): ERROR: code-after-endm-endr-endc.asm(17): syntax error, unexpected PRINTLN, expecting newline ERROR: code-after-endm-endr-endc.asm(19): - syntax error, unexpected PRINTLN, expecting end of file or newline + syntax error, unexpected PRINTLN, expecting newline ERROR: code-after-endm-endr-endc.asm(23): syntax error, unexpected PRINTLN, expecting newline ERROR: code-after-endm-endr-endc.asm(25): - syntax error, unexpected PRINTLN, expecting end of file or newline + syntax error, unexpected PRINTLN, expecting newline error: Assembly aborted (7 errors)!