diff --git a/Makefile b/Makefile index 39c98dd84d..ec1e379306 100644 --- a/Makefile +++ b/Makefile @@ -122,14 +122,17 @@ src/asm/parser.h: src/asm/parser.c $Qtouch $@ src/asm/parser.c: src/asm/parser.y - $QDEFS=; \ add_flag(){ \ if src/check_bison_ver.sh $$1 $$2; then \ - DEFS+=-D$$3; \ + DEFS="-D$$3 $$DEFS"; \ fi \ }; \ add_flag 3 5 api.token.raw=true; \ - ${BISON} -d $$DEFS ${YFLAGS} -o $@ $< + add_flag 3 6 parse.error=detailed; \ + add_flag 3 0 parse.error=verbose; \ + add_flag 3 0 parse.lac=full; \ + echo "DEFS=$$DEFS" + ${BISON} $$DEFS -d ${YFLAGS} -o $@ $< .c.o: $Q${CC} ${REALCFLAGS} ${PNGCFLAGS} -c -o $@ $< diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bdc9bfa0ad..e07e118c43 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,11 +21,16 @@ else() endif() find_package(BISON REQUIRED) -set(BISON_FLAGS "") +set(BISON_FLAGS "-Dparse.lac=full") # Set sompe optimization flags on versions that support them if(BISON_VERSION VERSION_GREATER_EQUAL "3.5") set(BISON_FLAGS "${BISON_FLAGS} -Dapi.token.raw=true") endif() +if(BISON_VERSION VERSION_GREATER_EQUAL "3.6") + set(BISON_FLAGS "${BISON_FLAGS} -Dparse.error=detailed") +elseif(BISON_VERSION VERSION_GREATER_EQUAL "3.0") + set(BISON_FLAGS "${BISON_FLAGS} -Dparse.error=verbose") +endif() BISON_TARGET(PARSER "asm/parser.y" "${PROJECT_SOURCE_DIR}/src/asm/parser.c" COMPILE_FLAGS "${BISON_FLAGS}" diff --git a/src/asm/parser.y b/src/asm/parser.y index f9bdc00fd0..efa7e8c19d 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -177,7 +177,17 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg) } } -#define yyerror(str) error(str "\n") +void yyerror(char const *str) +{ + size_t len = strlen(str); + char *buf = malloc(len + 2); + + memcpy(buf, str, len); + buf[len] = '\n'; + buf[len + 1] = '\0'; + error(buf); + free(buf); +} %} @@ -209,94 +219,117 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg) %type sectorg %type sectattrs -%token T_NUMBER -%token T_STRING - -%left T_COMMA -%left T_COLON -%left T_LBRACK -%left T_RBRACK -%left T_LPAREN -%left T_RPAREN -%left T_NEWLINE - -%left T_OP_LOGICNOT -%left T_OP_LOGICOR T_OP_LOGICAND +%token T_NUMBER "number" +%token T_STRING "string" + +%token T_COMMA "," +%token T_COLON ":" +%token T_LBRACK "[" +%token T_RBRACK "]" +%token T_LPAREN "(" +%token T_RPAREN ")" +%token T_NEWLINE "newline" +%left T_COMMA T_COLON T_LBRACK T_RBRACK T_LPAREN T_RPAREN T_NEWLINE + +%token T_OP_LOGICNOT "!" +%token T_OP_LOGICOR "||" +%token T_OP_LOGICAND "&&" +%token T_OP_LOGICGT ">" +%token T_OP_LOGICLT "<" +%token T_OP_LOGICGE ">=" +%token T_OP_LOGICLE "<=" +%token T_OP_LOGICNE "!=" +%token T_OP_LOGICEQU "==" +%token T_OP_ADD "+" +%token T_OP_SUB "-" +%token T_OP_OR "|" +%token T_OP_XOR "^" +%token T_OP_AND "&" +%token T_OP_SHL "<<" +%token T_OP_SHR ">>" +%token T_OP_MUL "*" +%token T_OP_DIV "/" +%token T_OP_MOD "%" +%token T_OP_NOT "not" +%token T_OP_DEF "def" +%token T_OP_BANK "bank" +%token T_OP_ALIGN "align" +%token T_OP_SIN "sin" +%token T_OP_COS "cos" +%token T_OP_TAN "tan" +%token T_OP_ASIN "asin" +%token T_OP_ACOS "acos" +%token T_OP_ATAN "atan" +%token T_OP_ATAN2 "atan2" +%token T_OP_FDIV "fdiv" +%token T_OP_FMUL "fmul" +%token T_OP_ROUND "round" +%token T_OP_CEIL "ceil" +%token T_OP_FLOOR "floor" +%left T_OP_LOGICNOT T_OP_LOGICOR T_OP_LOGICAND %left T_OP_LOGICGT T_OP_LOGICLT T_OP_LOGICGE T_OP_LOGICLE T_OP_LOGICNE T_OP_LOGICEQU -%left T_OP_ADD T_OP_SUB -%left T_OP_OR T_OP_XOR T_OP_AND -%left T_OP_SHL T_OP_SHR -%left T_OP_MUL T_OP_DIV T_OP_MOD -%left T_OP_NOT -%left T_OP_DEF -%left T_OP_BANK T_OP_ALIGN -%left T_OP_SIN -%left T_OP_COS -%left T_OP_TAN -%left T_OP_ASIN -%left T_OP_ACOS -%left T_OP_ATAN -%left T_OP_ATAN2 -%left T_OP_FDIV -%left T_OP_FMUL -%left T_OP_ROUND -%left T_OP_CEIL -%left T_OP_FLOOR - -%token T_OP_HIGH T_OP_LOW +%left T_OP_ADD T_OP_SUB T_OP_OR T_OP_XOR T_OP_AND T_OP_SHL T_OP_SHR T_OP_MUL T_OP_DIV T_OP_MOD T_OP_NOT +%left T_OP_DEF T_OP_BANK T_OP_ALIGN +%left T_OP_SIN T_OP_COS T_OP_TAN T_OP_ASIN T_OP_ACOS T_OP_ATAN T_OP_ATAN2 +%left T_OP_FDIV T_OP_FMUL T_OP_ROUND T_OP_CEIL T_OP_FLOOR + +%token T_OP_HIGH "high" +%token T_OP_LOW "low" %token T_OP_ISCONST -%left T_OP_STRCMP -%left T_OP_STRIN -%left T_OP_STRRIN -%left T_OP_STRSUB -%left T_OP_STRLEN -%left T_OP_STRCAT -%left T_OP_STRUPR -%left T_OP_STRLWR +%token T_OP_STRCMP "strcmp" +%token T_OP_STRIN "strin" +%token T_OP_STRRIN "strrin" +%token T_OP_STRSUB "strsub" +%token T_OP_STRLEN "strlen" +%token T_OP_STRCAT "strcat" +%token T_OP_STRUPR "strupr" +%token T_OP_STRLWR "strlwr" +%left T_OP_STRCMP T_OP_STRIN T_OP_STRRIN T_OP_STRSUB T_OP_STRLEN T_OP_STRCAT T_OP_STRUPR T_OP_STRLWR %left NEG /* negation -- unary minus */ -%token T_LABEL -%token T_ID -%token T_LOCAL_ID +%token T_LABEL "label" +%token T_ID "identifier" +%token T_LOCAL_ID "local identifier" %type scoped_id -%token T_POP_EQU -%token T_POP_SET -%token T_POP_EQUAL -%token T_POP_EQUS - -%token T_POP_INCLUDE T_POP_PRINTF T_POP_PRINTT T_POP_PRINTV T_POP_PRINTI -%token T_POP_IF T_POP_ELIF T_POP_ELSE T_POP_ENDC -%token T_POP_EXPORT T_POP_GLOBAL T_POP_XDEF -%token T_POP_DB T_POP_DS T_POP_DW T_POP_DL -%token T_POP_SECTION T_POP_FRAGMENT -%token T_POP_RB -%token T_POP_RW -%token T_POP_RL -%token T_POP_MACRO -%token T_POP_ENDM -%token T_POP_RSRESET T_POP_RSSET -%token T_POP_UNION T_POP_NEXTU T_POP_ENDU -%token T_POP_INCBIN T_POP_REPT -%token T_POP_CHARMAP -%token T_POP_NEWCHARMAP -%token T_POP_SETCHARMAP -%token T_POP_PUSHC -%token T_POP_POPC -%token T_POP_SHIFT -%token T_POP_ENDR -%token T_POP_LOAD T_POP_ENDL -%token T_POP_FAIL -%token T_POP_WARN -%token T_POP_FATAL -%token T_POP_ASSERT T_POP_STATIC_ASSERT -%token T_POP_PURGE -%token T_POP_POPS -%token T_POP_PUSHS -%token T_POP_POPO -%token T_POP_PUSHO -%token T_POP_OPT +%token T_POP_EQU "equ" +%token T_POP_SET "set" +%token T_POP_EQUAL "=" +%token T_POP_EQUS "equs" + +%token T_POP_INCLUDE "include" +%token T_POP_PRINTF "printf" T_POP_PRINTT "printt" T_POP_PRINTV "printv" T_POP_PRINTI "printi" +%token T_POP_IF "if" T_POP_ELIF "elif" T_POP_ELSE "else" T_POP_ENDC "endc" +%token T_POP_EXPORT "export" T_POP_GLOBAL "global" T_POP_XDEF "xdef" +%token T_POP_DB "db" T_POP_DS "ds" T_POP_DW "dw" T_POP_DL "dl" +%token T_POP_SECTION "section" T_POP_FRAGMENT "fragment" +%token T_POP_RB "rb" +%token T_POP_RW "rw" +%token T_POP_RL "rl" +%token T_POP_MACRO "macro" +%token T_POP_ENDM "endm" +%token T_POP_RSRESET "rsreset" T_POP_RSSET "rsset" +%token T_POP_UNION "union" T_POP_NEXTU "nextu" T_POP_ENDU "endu" +%token T_POP_INCBIN "incbin" T_POP_REPT "rept" +%token T_POP_CHARMAP "charmap" +%token T_POP_NEWCHARMAP "newcharmap" +%token T_POP_SETCHARMAP "setcharmap" +%token T_POP_PUSHC "pushc" +%token T_POP_POPC "popc" +%token T_POP_SHIFT "shift" +%token T_POP_ENDR "endr" +%token T_POP_LOAD "load" T_POP_ENDL "endl" +%token T_POP_FAIL "fail" +%token T_POP_WARN "warn" +%token T_POP_FATAL "fatal" +%token T_POP_ASSERT "assert" T_POP_STATIC_ASSERT "static_assert" +%token T_POP_PURGE "purge" +%token T_POP_POPS "pops" +%token T_POP_PUSHS "pushs" +%token T_POP_POPO "popo" +%token T_POP_PUSHO "pusho" +%token T_POP_OPT "opt" %token T_SECT_WRAM0 T_SECT_VRAM T_SECT_ROMX T_SECT_ROM0 T_SECT_HRAM %token T_SECT_WRAMX T_SECT_SRAM T_SECT_OAM diff --git a/test/asm/block-comment-termination-error.err b/test/asm/block-comment-termination-error.err index 770bc9e952..f5e82102af 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 + syntax error, unexpected newline error: Assembly aborted (2 errors)! diff --git a/test/asm/label-macro-arg.asm b/test/asm/label-macro-arg.asm index 24c1e04014..d3d0a01001 100644 --- a/test/asm/label-macro-arg.asm +++ b/test/asm/label-macro-arg.asm @@ -41,5 +41,5 @@ ENDM test_char @ test_char # - test_char . test_char : + test_char . diff --git a/test/asm/label-macro-arg.err b/test/asm/label-macro-arg.err index 70c50a221e..014de73dfa 100644 --- a/test/asm/label-macro-arg.err +++ b/test/asm/label-macro-arg.err @@ -1,7 +1,17 @@ ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(31): - Local label 'sizeof_.something' in main scope + Label "sizeof_" created outside of a SECTION while expanding symbol "VAR_DEF" ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(31): - syntax error + Macro "something" not defined +ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(32): + 'sizeof_' already defined at label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(31) +ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(32): + Macro "something" not defined +ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(35): + Print types are exactly 1 character long +ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(35): + Interpolated symbol "something" does not exist +ERROR: label-macro-arg.asm(45) -> label-macro-arg.asm::test_char(31): + syntax error, unexpected = while expanding symbol "VAR_DEF" -error: Assembly aborted (2 errors)! +error: Assembly aborted (7 errors)! diff --git a/test/asm/label-macro-arg.out b/test/asm/label-macro-arg.out index 26e33473ec..0564ea5ac8 100644 --- a/test/asm/label-macro-arg.out +++ b/test/asm/label-macro-arg.out @@ -5,3 +5,4 @@ $8 sizeof__something equals $1 sizeof_@something equals $1 sizeof_#something equals $1 +sizeof_:something equals