mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Add debug tracing code to lexer
Hidden behind a #define, like YYDEBUG
This commit is contained in:
@@ -21,6 +21,12 @@
|
|||||||
#include "asm/warning.h"
|
#include "asm/warning.h"
|
||||||
#include "platform.h" /* S_ISDIR (stat macro) */
|
#include "platform.h" /* S_ISDIR (stat macro) */
|
||||||
|
|
||||||
|
#ifdef LEXER_DEBUG
|
||||||
|
#define dbgPrint(...) fprintf(stderr, "[lexer] " __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define dbgPrint(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
struct Context *parent;
|
struct Context *parent;
|
||||||
struct Context *child;
|
struct Context *child;
|
||||||
@@ -145,6 +151,8 @@ bool yywrap(void)
|
|||||||
} else if (!contextStack->parent) {
|
} else if (!contextStack->parent) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
dbgPrint("Popping context\n");
|
||||||
|
|
||||||
contextStack = contextStack->parent;
|
contextStack = contextStack->parent;
|
||||||
contextDepth--;
|
contextDepth--;
|
||||||
|
|
||||||
@@ -178,6 +186,8 @@ static void newContext(uint32_t reptDepth)
|
|||||||
|
|
||||||
void fstk_RunInclude(char const *path)
|
void fstk_RunInclude(char const *path)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Including path \"%s\"\n", path);
|
||||||
|
|
||||||
char *fullPath = NULL;
|
char *fullPath = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
|
||||||
@@ -186,6 +196,7 @@ void fstk_RunInclude(char const *path)
|
|||||||
error("Unable to open included file '%s': %s\n", path, strerror(errno));
|
error("Unable to open included file '%s': %s\n", path, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
dbgPrint("Full path: \"%s\"\n", fullPath);
|
||||||
|
|
||||||
newContext(0);
|
newContext(0);
|
||||||
contextStack->lexerState = lexer_OpenFile(fullPath);
|
contextStack->lexerState = lexer_OpenFile(fullPath);
|
||||||
@@ -202,6 +213,8 @@ void fstk_RunInclude(char const *path)
|
|||||||
|
|
||||||
void fstk_RunMacro(char *macroName, struct MacroArgs *args)
|
void fstk_RunMacro(char *macroName, struct MacroArgs *args)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Running macro \"%s\"\n", macroName);
|
||||||
|
|
||||||
struct Symbol *macro = sym_FindSymbol(macroName);
|
struct Symbol *macro = sym_FindSymbol(macroName);
|
||||||
|
|
||||||
if (!macro) {
|
if (!macro) {
|
||||||
@@ -229,6 +242,8 @@ void fstk_RunMacro(char *macroName, struct MacroArgs *args)
|
|||||||
|
|
||||||
void fstk_RunRept(uint32_t count, int32_t nReptLineNo, char *body, size_t size)
|
void fstk_RunRept(uint32_t count, int32_t nReptLineNo, char *body, size_t size)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Running REPT(%" PRIu32 ")\n", count);
|
||||||
|
|
||||||
uint32_t reptDepth = contextStack->reptDepth;
|
uint32_t reptDepth = contextStack->reptDepth;
|
||||||
|
|
||||||
newContext(reptDepth + 1);
|
newContext(reptDepth + 1);
|
||||||
|
|||||||
@@ -35,6 +35,12 @@
|
|||||||
/* Include this last so it gets all type & constant definitions */
|
/* Include this last so it gets all type & constant definitions */
|
||||||
#include "asmy.h" /* For token definitions, generated from asmy.y */
|
#include "asmy.h" /* For token definitions, generated from asmy.y */
|
||||||
|
|
||||||
|
#ifdef LEXER_DEBUG
|
||||||
|
#define dbgPrint(...) fprintf(stderr, "[lexer] " __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define dbgPrint(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Identifiers that are also keywords are listed here. This ONLY applies to ones
|
* Identifiers that are also keywords are listed here. This ONLY applies to ones
|
||||||
* that would normally be matched as identifiers! Check out `yylex_NORMAL` to
|
* that would normally be matched as identifiers! Check out `yylex_NORMAL` to
|
||||||
@@ -296,6 +302,8 @@ static void initState(struct LexerState *state)
|
|||||||
|
|
||||||
struct LexerState *lexer_OpenFile(char const *path)
|
struct LexerState *lexer_OpenFile(char const *path)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Opening file \"%s\"\n", path);
|
||||||
|
|
||||||
bool isStdin = !strcmp(path, "-");
|
bool isStdin = !strcmp(path, "-");
|
||||||
struct LexerState *state = malloc(sizeof(*state));
|
struct LexerState *state = malloc(sizeof(*state));
|
||||||
|
|
||||||
@@ -370,6 +378,8 @@ struct LexerState *lexer_OpenFile(char const *path)
|
|||||||
|
|
||||||
struct LexerState *lexer_OpenFileView(char *buf, size_t size, uint32_t lineNo)
|
struct LexerState *lexer_OpenFileView(char *buf, size_t size, uint32_t lineNo)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Opening view on buffer \"%.*s\"[...]\n", size < 16 ? (int)size : 16, buf);
|
||||||
|
|
||||||
struct LexerState *state = malloc(sizeof(*state));
|
struct LexerState *state = malloc(sizeof(*state));
|
||||||
|
|
||||||
if (!state) {
|
if (!state) {
|
||||||
@@ -391,6 +401,7 @@ struct LexerState *lexer_OpenFileView(char *buf, size_t size, uint32_t lineNo)
|
|||||||
|
|
||||||
void lexer_RestartRept(uint32_t lineNo)
|
void lexer_RestartRept(uint32_t lineNo)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Restarting REPT\n");
|
||||||
lexerState->offset = 0;
|
lexerState->offset = 0;
|
||||||
initState(lexerState);
|
initState(lexerState);
|
||||||
lexerState->lineNo = lineNo;
|
lexerState->lineNo = lineNo;
|
||||||
@@ -840,6 +851,7 @@ void lexer_DumpStringExpansions(void)
|
|||||||
|
|
||||||
static void discardComment(void)
|
static void discardComment(void)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Discarding comment\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
|
||||||
@@ -858,6 +870,7 @@ static bool isWhitespace(int c)
|
|||||||
|
|
||||||
static void readLineContinuation(void)
|
static void readLineContinuation(void)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Beginning line continuation\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
|
||||||
@@ -903,6 +916,7 @@ static void readFractionalPart(void)
|
|||||||
{
|
{
|
||||||
uint32_t value = 0, divisor = 1;
|
uint32_t value = 0, divisor = 1;
|
||||||
|
|
||||||
|
dbgPrint("Reading fractional part\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
|
||||||
@@ -933,6 +947,7 @@ static void readBinaryNumber(void)
|
|||||||
{
|
{
|
||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
|
|
||||||
|
dbgPrint("Reading binary number\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
|
||||||
@@ -952,6 +967,7 @@ static void readHexNumber(void)
|
|||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
|
|
||||||
|
dbgPrint("Reading hex number\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
|
||||||
@@ -983,6 +999,7 @@ static void readGfxConstant(void)
|
|||||||
uint32_t bp0 = 0, bp1 = 0;
|
uint32_t bp0 = 0, bp1 = 0;
|
||||||
uint8_t width = 0;
|
uint8_t width = 0;
|
||||||
|
|
||||||
|
dbgPrint("Reading gfx constant\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
|
||||||
@@ -1018,6 +1035,7 @@ static bool startsIdentifier(int c)
|
|||||||
|
|
||||||
static int readIdentifier(char firstChar)
|
static int readIdentifier(char firstChar)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Reading identifier or keyword\n");
|
||||||
/* Lex while checking for a keyword */
|
/* Lex while checking for a keyword */
|
||||||
yylval.tzSym[0] = firstChar;
|
yylval.tzSym[0] = firstChar;
|
||||||
uint16_t nodeID = keywordDict[0].children[dictIndex(firstChar)];
|
uint16_t nodeID = keywordDict[0].children[dictIndex(firstChar)];
|
||||||
@@ -1053,6 +1071,7 @@ static int readIdentifier(char firstChar)
|
|||||||
i = sizeof(yylval.tzSym) - 1;
|
i = sizeof(yylval.tzSym) - 1;
|
||||||
}
|
}
|
||||||
yylval.tzSym[i] = '\0'; /* Terminate the string */
|
yylval.tzSym[i] = '\0'; /* Terminate the string */
|
||||||
|
dbgPrint("Ident/keyword = \"%s\"\n", yylval.tzSym);
|
||||||
|
|
||||||
if (keywordDict[nodeID].keyword)
|
if (keywordDict[nodeID].keyword)
|
||||||
return keywordDict[nodeID].keyword->token;
|
return keywordDict[nodeID].keyword->token;
|
||||||
@@ -1193,6 +1212,7 @@ static void readString(void)
|
|||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
|
dbgPrint("Reading string\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
|
||||||
@@ -1204,6 +1224,7 @@ static void readString(void)
|
|||||||
warning(WARNING_LONG_STR, "String constant too long\n");
|
warning(WARNING_LONG_STR, "String constant too long\n");
|
||||||
}
|
}
|
||||||
yylval.tzString[i] = '\0';
|
yylval.tzString[i] = '\0';
|
||||||
|
dbgPrint("Read string \"%s\"\n", yylval.tzString);
|
||||||
return;
|
return;
|
||||||
case '\r':
|
case '\r':
|
||||||
case '\n': /* Do not shift these! */
|
case '\n': /* Do not shift these! */
|
||||||
@@ -1214,6 +1235,7 @@ static void readString(void)
|
|||||||
}
|
}
|
||||||
yylval.tzString[i] = '\0';
|
yylval.tzString[i] = '\0';
|
||||||
error("Unterminated string\n");
|
error("Unterminated string\n");
|
||||||
|
dbgPrint("Read string \"%s\"\n", yylval.tzString);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case '\\': /* Character escape */
|
case '\\': /* Character escape */
|
||||||
@@ -1330,6 +1352,7 @@ static char const *reportGarbageChar(unsigned char firstByte)
|
|||||||
|
|
||||||
static int yylex_NORMAL(void)
|
static int yylex_NORMAL(void)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Lexing in normal mode\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = nextChar();
|
int c = nextChar();
|
||||||
|
|
||||||
@@ -1534,6 +1557,8 @@ static int yylex_NORMAL(void)
|
|||||||
|
|
||||||
static int yylex_RAW(void)
|
static int yylex_RAW(void)
|
||||||
{
|
{
|
||||||
|
dbgPrint("Lexing in raw mode\n");
|
||||||
|
|
||||||
/* This is essentially a modified `readString` */
|
/* This is essentially a modified `readString` */
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
bool insideString = false;
|
bool insideString = false;
|
||||||
@@ -1576,6 +1601,7 @@ static int yylex_RAW(void)
|
|||||||
return c == EOF ? 0 : c;
|
return c == EOF ? 0 : c;
|
||||||
}
|
}
|
||||||
yylval.tzString[i] = '\0';
|
yylval.tzString[i] = '\0';
|
||||||
|
dbgPrint("Read raw string \"%s\"\n", yylval.tzString);
|
||||||
return T_STRING;
|
return T_STRING;
|
||||||
|
|
||||||
case '\\': /* Character escape */
|
case '\\': /* Character escape */
|
||||||
@@ -1699,12 +1725,15 @@ restart:
|
|||||||
/* Make sure to terminate files with a line feed */
|
/* Make sure to terminate files with a line feed */
|
||||||
if (token == 0) {
|
if (token == 0) {
|
||||||
if (lexerState->lastToken != '\n') {
|
if (lexerState->lastToken != '\n') {
|
||||||
|
dbgPrint("Forcing EOL at EOF\n");
|
||||||
token = '\n';
|
token = '\n';
|
||||||
} else { /* Try to switch to new buffer; if it succeeds, scan again */
|
} 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 */
|
/* Captures end at their buffer's boundary no matter what */
|
||||||
if (!lexerState->capturing) {
|
if (!lexerState->capturing) {
|
||||||
if (!yywrap())
|
if (!yywrap())
|
||||||
goto restart;
|
goto restart;
|
||||||
|
dbgPrint("Reached end of input.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user