From e3d355d9762b5f50697274b25b685a0e3c16981a Mon Sep 17 00:00:00 2001 From: Rangi Date: Thu, 21 Jan 2021 09:36:10 -0500 Subject: [PATCH] Attempt to recover from syntax errors with bison Fixes #595 --- include/asm/fstack.h | 1 + src/asm/fstack.c | 9 +++++++-- src/asm/parser.y | 3 +++ test/asm/error-recovery.asm | 11 +++++++++++ test/asm/error-recovery.err | 5 +++++ test/asm/error-recovery.out | 4 ++++ test/asm/error-recovery.simple.err | 5 +++++ test/asm/label-macro-arg.err | 17 ++++++++++++++++- test/asm/label-macro-arg.out | 2 ++ test/asm/label-macro-arg.simple.err | 19 ++++++++++++++++++- 10 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 test/asm/error-recovery.asm create mode 100644 test/asm/error-recovery.err create mode 100644 test/asm/error-recovery.out create mode 100644 test/asm/error-recovery.simple.err diff --git a/include/asm/fstack.h b/include/asm/fstack.h index f3577272..87870819 100644 --- a/include/asm/fstack.h +++ b/include/asm/fstack.h @@ -78,6 +78,7 @@ void fstk_RunMacro(char const *macroName, struct MacroArgs *args); void fstk_RunRept(uint32_t count, int32_t nReptLineNo, char *body, size_t size); void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step, int32_t reptLineNo, char *body, size_t size); +void fstk_StopRept(void); bool fstk_Break(void); void fstk_Init(char const *mainPath, size_t maxRecursionDepth); diff --git a/src/asm/fstack.c b/src/asm/fstack.c index 175843d4..bf2c7415 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -506,6 +506,12 @@ void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step, fatalerror("Not enough memory for FOR symbol name: %s\n", strerror(errno)); } +void fstk_StopRept(void) +{ + /* Prevent more iterations */ + contextStack->nbReptIters = 0; +} + bool fstk_Break(void) { dbgPrint("Breaking out of REPT/FOR\n"); @@ -515,8 +521,7 @@ bool fstk_Break(void) return false; } - /* Prevent more iterations */ - contextStack->nbReptIters = 0; + fstk_StopRept(); return true; } diff --git a/src/asm/parser.y b/src/asm/parser.y index c3feda54..1ce9e7a7 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -609,6 +609,9 @@ line : label 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/error-recovery.asm b/test/asm/error-recovery.asm new file mode 100644 index 00000000..3136bc51 --- /dev/null +++ b/test/asm/error-recovery.asm @@ -0,0 +1,11 @@ + println "begin" + + println 42, 1 2 3 4 + +for n, 5 + println "start {d:n}" + println syntax error + println "finish {d:n}" +endr + + println "end {d:n}" diff --git a/test/asm/error-recovery.err b/test/asm/error-recovery.err new file mode 100644 index 00000000..f3c64cd6 --- /dev/null +++ b/test/asm/error-recovery.err @@ -0,0 +1,5 @@ +ERROR: error-recovery.asm(3): + syntax error, unexpected number +ERROR: error-recovery.asm(5) -> error-recovery.asm::REPT~1(7): + syntax error, unexpected identifier +error: Assembly aborted (2 errors)! diff --git a/test/asm/error-recovery.out b/test/asm/error-recovery.out new file mode 100644 index 00000000..c8f0b99a --- /dev/null +++ b/test/asm/error-recovery.out @@ -0,0 +1,4 @@ +begin +$2Astart 0 +finish 0 +end 0 diff --git a/test/asm/error-recovery.simple.err b/test/asm/error-recovery.simple.err new file mode 100644 index 00000000..b9582e68 --- /dev/null +++ b/test/asm/error-recovery.simple.err @@ -0,0 +1,5 @@ +ERROR: error-recovery.asm(3): + syntax error +ERROR: error-recovery.asm(5) -> error-recovery.asm::REPT~1(7): + syntax error +error: Assembly aborted (2 errors)! diff --git a/test/asm/label-macro-arg.err b/test/asm/label-macro-arg.err index 084316dd..240e8651 100644 --- a/test/asm/label-macro-arg.err +++ b/test/asm/label-macro-arg.err @@ -1,4 +1,19 @@ ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(25): syntax error, unexpected = while expanding symbol "VAR_DEF" -error: Assembly aborted (1 errors)! +ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(29): + Interpolated symbol "sizeof_.something" does not exist +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25): + Label "sizeof_" created outside of a SECTION +while expanding symbol "VAR_DEF" +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25): + Macro "something" not defined +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(26): + 'sizeof_' already defined at label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25) +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(26): + Macro "something" not defined +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(29): + Invalid format spec 'sizeof_' +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(29): + Interpolated symbol "something" does not exist +error: Assembly aborted (8 errors)! diff --git a/test/asm/label-macro-arg.out b/test/asm/label-macro-arg.out index 26e33473..106412e2 100644 --- a/test/asm/label-macro-arg.out +++ b/test/asm/label-macro-arg.out @@ -5,3 +5,5 @@ $8 sizeof__something equals $1 sizeof_@something equals $1 sizeof_#something equals $1 +sizeof_.something equals +sizeof_:something equals diff --git a/test/asm/label-macro-arg.simple.err b/test/asm/label-macro-arg.simple.err index d8e93837..ba199e93 100644 --- a/test/asm/label-macro-arg.simple.err +++ b/test/asm/label-macro-arg.simple.err @@ -4,4 +4,21 @@ while expanding symbol "VAR_DEF" ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(25): syntax error while expanding symbol "VAR_DEF" -error: Assembly aborted (2 errors)! +ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(26): + Local label 'sizeof_.something' in main scope +ERROR: label-macro-arg.asm(38) -> label-macro-arg.asm::test_char(29): + Interpolated symbol "sizeof_.something" does not exist +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25): + Label "sizeof_" created outside of a SECTION +while expanding symbol "VAR_DEF" +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25): + Macro "something" not defined +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(26): + 'sizeof_' already defined at label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(25) +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(26): + Macro "something" not defined +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(29): + Invalid format spec 'sizeof_' +ERROR: label-macro-arg.asm(39) -> label-macro-arg.asm::test_char(29): + Interpolated symbol "something" does not exist +error: Assembly aborted (10 errors)!