From 6c1f17339ac1a3078449fb4418aa660f582c0ea2 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 ace823720..5c1422235 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 7416a667e..a80d4f173 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -501,6 +501,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"); @@ -510,8 +516,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 ccbd9661b..8d38b76c0 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -576,6 +576,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 000000000..3136bc519 --- /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 000000000..f3c64cd67 --- /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 000000000..c8f0b99aa --- /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 000000000..b9582e68c --- /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 084316dd2..240e86516 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 26e33473e..106412e24 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 d8e938379..ba199e931 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)!