Skip to content

Commit

Permalink
Use more verbose syntax error messages
Browse files Browse the repository at this point in the history
Fixes the long-standing gbdev#385
  • Loading branch information
ISSOtm committed Dec 10, 2020
1 parent e54e02d commit cffc246
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 91 deletions.
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 $@ $<
Expand Down
7 changes: 6 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down
197 changes: 115 additions & 82 deletions src/asm/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

%}

Expand Down Expand Up @@ -209,94 +219,117 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg)
%type <nConstValue> sectorg
%type <sectSpec> sectattrs

%token <nConstValue> T_NUMBER
%token <tzString> 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 <nConstValue> T_NUMBER "number"
%token <tzString> 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 <tzSym> T_LABEL
%token <tzSym> T_ID
%token <tzSym> T_LOCAL_ID
%token <tzSym> T_LABEL "label"
%token <tzSym> T_ID "identifier"
%token <tzSym> T_LOCAL_ID "local identifier"
%type <tzSym> 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

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
syntax error, unexpected newline
error: Assembly aborted (2 errors)!
2 changes: 1 addition & 1 deletion test/asm/label-macro-arg.asm
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ ENDM
test_char @
test_char #

test_char .
test_char :
test_char .
16 changes: 13 additions & 3 deletions test/asm/label-macro-arg.err
Original file line number Diff line number Diff line change
@@ -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)!
1 change: 1 addition & 0 deletions test/asm/label-macro-arg.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ $8
sizeof__something equals $1
sizeof_@something equals $1
sizeof_#something equals $1
sizeof_:something equals

0 comments on commit cffc246

Please sign in to comment.