Skip to content

Commit

Permalink
Return a marker token at the end of any buffer
Browse files Browse the repository at this point in the history
Removes the lexer hack mentioned in #778
  • Loading branch information
Rangi42 committed Apr 19, 2021
1 parent e355859 commit 7e74841
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 42 deletions.
1 change: 1 addition & 0 deletions include/asm/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct CaptureBody {
uint32_t lineNo;
char *body;
size_t size;
bool unterminated;
};

char const *lexer_GetFileName(void);
Expand Down
34 changes: 18 additions & 16 deletions src/asm/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ struct LexerState {
uint32_t colNo;
int lastToken;
int nextToken;
bool isAtEOF;

struct IfStack *ifStack;

Expand All @@ -378,6 +379,7 @@ static void initState(struct LexerState *state)
state->atLineStart = true; /* yylex() will init colNo due to this */
state->lastToken = T_EOF;
state->nextToken = 0;
state->isAtEOF = false;

state->ifStack = NULL;

Expand Down Expand Up @@ -2267,11 +2269,13 @@ static int yylex_SKIP_TO_ENDR(void)

int yylex(void)
{
restart:
if (lexerState->atLineStart && lexerStateEOL) {
if (lexerStateEOL) {
lexer_SetState(lexerStateEOL);
lexerStateEOL = NULL;
}
/* `lexer_SetState` updates `lexerState`, so check for EOF after it */
if (lexerState->isAtEOF)
return T_EOF;
if (lexerState->atLineStart) {
/* Newlines read within an expansion should not increase the line count */
if (!lexerState->expansions)
Expand All @@ -2288,23 +2292,19 @@ int yylex(void)
int token = lexerModeFuncs[lexerState->mode]();

if (token == 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;
/* 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()) {
dbgPrint("Reached end of input.\n");
return T_EOF;
lexerState->isAtEOF = true;
}
token = T_EOB;
}
}
lexerState->lastToken = token;
lexerState->atLineStart = token == T_NEWLINE;
lexerState->atLineStart = token == T_NEWLINE || token == T_EOB;

return token;
}
Expand All @@ -2327,6 +2327,7 @@ static char *startCapture(void)

void lexer_CaptureRept(struct CaptureBody *capture)
{
capture->unterminated = false;
capture->lineNo = lexer_GetLineNo();

char *captureStart = startCapture();
Expand Down Expand Up @@ -2361,7 +2362,6 @@ 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--;
Expand All @@ -2372,6 +2372,7 @@ void lexer_CaptureRept(struct CaptureBody *capture)
for (;;) {
if (c == EOF) {
error("Unterminated REPT/FOR block\n");
capture->unterminated = true;
goto finish;
} else if (c == '\n' || c == '\r') {
handleCRLF(c);
Expand All @@ -2393,6 +2394,7 @@ void lexer_CaptureRept(struct CaptureBody *capture)

void lexer_CaptureMacroBody(struct CaptureBody *capture)
{
capture->unterminated = false;
capture->lineNo = lexer_GetLineNo();

char *captureStart = startCapture();
Expand Down Expand Up @@ -2423,7 +2425,6 @@ 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;
}
}
Expand All @@ -2432,6 +2433,7 @@ void lexer_CaptureMacroBody(struct CaptureBody *capture)
for (;;) {
if (c == EOF) {
error("Unterminated macro definition\n");
capture->unterminated = true;
goto finish;
} else if (c == '\n' || c == '\r') {
handleCRLF(c);
Expand Down
47 changes: 27 additions & 20 deletions src/asm/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ enum {
%type <sVal> op_mem_ind
%type <assertType> assert_type

%token T_EOB "end of buffer"
%token T_EOF 0 "end of file"
%start asmfile

Expand All @@ -646,24 +647,23 @@ enum {
asmfile : lines
;

/*
* The lexer adds T_NEWLINE at the end of the file if one was not
* already present, so we can rely on it to end a line.
*/
lines : %empty
| lines line
;

endofline : T_NEWLINE | T_EOB
;

plain_directive : label
| label cpu_command
| label macro
| label directive
| assignment_directive
;

line : plain_directive T_NEWLINE
line : plain_directive endofline
| line_directive /* Directives that manage newlines themselves */
| error T_NEWLINE { /* Continue parsing the next line on a syntax error */
| error endofline { /* Continue parsing the next line on a syntax error */
fstk_StopRept();
}
;
Expand All @@ -678,6 +678,7 @@ line_directive : macrodef
| rept
| for
| break
| include
| if
/* It's important that all of these require being at line start for `skipIfBlock` */
| elif
Expand Down Expand Up @@ -799,8 +800,7 @@ assignment_directive : equ
| equs
;

directive : include
| endc
directive : endc
| print
| println
| printf
Expand Down Expand Up @@ -980,8 +980,10 @@ load : T_POP_LOAD sectmod string T_COMMA sectiontype sectorg sectattrs {

rept : T_POP_REPT uconst T_NEWLINE {
lexer_CaptureRept(&captureBody);
} T_NEWLINE {
fstk_RunRept($2, captureBody.lineNo, captureBody.body, captureBody.size);
} endofline {
if (!captureBody.unterminated)
fstk_RunRept($2, captureBody.lineNo, captureBody.body,
captureBody.size);
}
;

Expand All @@ -991,9 +993,10 @@ for : T_POP_FOR {
lexer_ToggleStringExpansion(true);
} T_COMMA for_args T_NEWLINE {
lexer_CaptureRept(&captureBody);
} T_NEWLINE {
fstk_RunFor($3, $6.start, $6.stop, $6.step, captureBody.lineNo,
captureBody.body, captureBody.size);
} endofline {
if (!captureBody.unterminated)
fstk_RunFor($3, $6.start, $6.stop, $6.step, captureBody.lineNo,
captureBody.body, captureBody.size);
}

for_args : const {
Expand All @@ -1013,7 +1016,7 @@ for_args : const {
}
;

break : T_POP_BREAK T_NEWLINE {
break : label T_POP_BREAK endofline {
if (fstk_Break())
lexer_SetMode(LEXER_SKIP_TO_ENDR);
}
Expand All @@ -1025,13 +1028,17 @@ macrodef : T_POP_MACRO {
lexer_ToggleStringExpansion(true);
} T_NEWLINE {
lexer_CaptureMacroBody(&captureBody);
} T_NEWLINE {
sym_AddMacro($3, captureBody.lineNo, captureBody.body, captureBody.size);
} endofline {
if (!captureBody.unterminated)
sym_AddMacro($3, captureBody.lineNo, captureBody.body,
captureBody.size);
}
| T_LABEL T_COLON T_POP_MACRO T_NEWLINE {
lexer_CaptureMacroBody(&captureBody);
} T_NEWLINE {
sym_AddMacro($1, captureBody.lineNo, captureBody.body, captureBody.size);
} endofline {
if (!captureBody.unterminated)
sym_AddMacro($1, captureBody.lineNo, captureBody.body,
captureBody.size);
}
;

Expand Down Expand Up @@ -1154,8 +1161,8 @@ export_list : export_list_entry
export_list_entry : scoped_id { sym_Export($1); }
;

include : T_POP_INCLUDE string {
fstk_RunInclude($2);
include : label T_POP_INCLUDE string endofline {
fstk_RunInclude($3);
if (oFailedOnMissingInclude)
YYACCEPT;
}
Expand Down
2 changes: 1 addition & 1 deletion test/asm/block-comment-termination-error.err
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ERROR: block-comment-termination-error.asm(1):
Unterminated block comment
ERROR: block-comment-termination-error.asm(1):
syntax error, unexpected newline
syntax error, unexpected end of buffer
error: Assembly aborted (2 errors)!
8 changes: 4 additions & 4 deletions test/asm/code-after-endm-endr-endc.err
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
ERROR: code-after-endm-endr-endc.asm(6):
syntax error, unexpected PRINTLN, expecting newline
syntax error, unexpected PRINTLN, expecting newline or end of buffer
ERROR: code-after-endm-endr-endc.asm(7):
Macro "mac" not defined
ERROR: code-after-endm-endr-endc.asm(12):
syntax error, unexpected PRINTLN, expecting newline
syntax error, unexpected PRINTLN, expecting newline or end of buffer
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 newline
syntax error, unexpected PRINTLN, expecting newline or end of buffer
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 newline
syntax error, unexpected PRINTLN, expecting newline or end of buffer
error: Assembly aborted (7 errors)!
2 changes: 1 addition & 1 deletion test/asm/nested-macrodef.err
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ warning: nested-macrodef.asm(26) -> nested-macrodef.asm::outer(22): [-Wuser]
ERROR: nested-macrodef.asm(26) -> nested-macrodef.asm::outer(24):
Unterminated macro definition
ERROR: nested-macrodef.asm(27):
syntax error, unexpected identifier, expecting newline
Macro "inner" not defined
error: Assembly aborted (2 errors)!

0 comments on commit 7e74841

Please sign in to comment.