ref: 46269240c84a9701804228909b81729f42a73f52
dir: /src/asm/lexer.c/
#include "asm/asm.h" #include "asm/lexer.h" #include "asm/types.h" #include "asm/main.h" #include "asm/rpn.h" #include "asm/fstack.h" #include "asmy.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> struct sLexString { char *tzName; ULONG nToken; ULONG nNameLength; struct sLexString *pNext; }; #define pLexBuffer (pCurrentBuffer->pBuffer) #define nLexBufferLeng (pCurrentBuffer->nBufferSize) #define SAFETYMARGIN 1024 extern ULONG symvaluetostring(char *dest, char *s); struct sLexFloat tLexFloat[32]; struct sLexString *tLexHash[LEXHASHSIZE]; YY_BUFFER_STATE pCurrentBuffer; ULONG yyleng; ULONG nLexMaxLeng; ULONG tFloatingSecondChar[256]; ULONG tFloatingFirstChar[256]; ULONG tFloatingChars[256]; ULONG nFloating; enum eLexerState lexerstate = LEX_STATE_NORMAL; #define AtLineStart pCurrentBuffer->oAtLineStart #ifdef __GNUC__ void strupr(char *s) { while (*s) { *s = toupper(*s); s += 1; } } void strlwr(char *s) { while (*s) { *s = tolower(*s); s += 1; } } #endif void yyskipbytes(ULONG count) { pLexBuffer += count; } void yyunputbytes(ULONG count) { pLexBuffer -= count; } void yyunput(char c) { *(--pLexBuffer) = c; } void yyunputstr(char *s) { SLONG i; i = strlen(s) - 1; while (i >= 0) yyunput(s[i--]); } void yy_switch_to_buffer(YY_BUFFER_STATE buf) { pCurrentBuffer = buf; } void yy_set_state(enum eLexerState i) { lexerstate = i; } void yy_delete_buffer(YY_BUFFER_STATE buf) { free(buf->pBufferStart - SAFETYMARGIN); free(buf); } YY_BUFFER_STATE yy_scan_bytes(char *mem, ULONG size) { YY_BUFFER_STATE pBuffer; if ((pBuffer = (YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) != NULL) { if ((pBuffer->pBuffer = pBuffer->pBufferStart = (char *) malloc(size + 1 + SAFETYMARGIN)) != NULL) { pBuffer->pBuffer += SAFETYMARGIN; pBuffer->pBufferStart += SAFETYMARGIN; memcpy(pBuffer->pBuffer, mem, size); pBuffer->nBufferSize = size; pBuffer->oAtLineStart = 1; pBuffer->pBuffer[size] = 0; return (pBuffer); } } fatalerror("Out of memory!"); return (NULL); } YY_BUFFER_STATE yy_create_buffer(FILE * f) { YY_BUFFER_STATE pBuffer; if ((pBuffer = (YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) != NULL) { ULONG size; fseek(f, 0, SEEK_END); size = ftell(f); fseek(f, 0, SEEK_SET); if ((pBuffer->pBuffer = pBuffer->pBufferStart = (char *) malloc(size + 2 + SAFETYMARGIN)) != NULL) { char *mem; ULONG instring = 0; pBuffer->pBuffer += SAFETYMARGIN; pBuffer->pBufferStart += SAFETYMARGIN; size = fread(pBuffer->pBuffer, sizeof(UBYTE), size, f); pBuffer->pBuffer[size] = '\n'; pBuffer->pBuffer[size + 1] = 0; pBuffer->nBufferSize = size + 1; mem = pBuffer->pBuffer; while (*mem) { if (*mem == '\"') instring = 1 - instring; if (instring) { mem += 1; } else { if ((mem[0] == 10 && mem[1] == 13) || (mem[0] == 13 && mem[1] == 10)) { mem[0] = ' '; mem[1] = '\n'; mem += 2; } else if (mem[0] == 10 || mem[0] == 13) { mem[0] = '\n'; mem += 1; } else if (mem[0] == '\n' && mem[1] == '*') { mem += 1; while (! (*mem == '\n' || *mem == '\0')) *mem++ = ' '; } else if (*mem == ';') { while (! (*mem == '\n' || *mem == '\0')) *mem++ = ' '; } else mem += 1; } } pBuffer->oAtLineStart = 1; return (pBuffer); } } fatalerror("Out of memory!"); return (NULL); } ULONG lex_FloatAlloc(struct sLexFloat * tok) { tLexFloat[nFloating] = (*tok); return (1 << (nFloating++)); } void lex_FloatDeleteRange(ULONG id, UWORD start, UWORD end) { while (start <= end) { tFloatingChars[start] &= ~id; start += 1; } } void lex_FloatAddRange(ULONG id, UWORD start, UWORD end) { while (start <= end) { tFloatingChars[start] |= id; start += 1; } } void lex_FloatDeleteFirstRange(ULONG id, UWORD start, UWORD end) { while (start <= end) { tFloatingFirstChar[start] &= ~id; start += 1; } } void lex_FloatAddFirstRange(ULONG id, UWORD start, UWORD end) { while (start <= end) { tFloatingFirstChar[start] |= id; start += 1; } } void lex_FloatDeleteSecondRange(ULONG id, UWORD start, UWORD end) { while (start <= end) { tFloatingSecondChar[start] &= ~id; start += 1; } } void lex_FloatAddSecondRange(ULONG id, UWORD start, UWORD end) { while (start <= end) { tFloatingSecondChar[start] |= id; start += 1; } } struct sLexFloat * lexgetfloat(ULONG id) { ULONG r = 0, mask = 1; if (id == 0) return (NULL); while ((id & mask) == 0) { mask <<= 1; r += 1; } return (&tLexFloat[r]); } ULONG lexcalchash(char *s) { ULONG r = 0; while (*s) { r = ((r << 1) + (toupper(*s))) % LEXHASHSIZE; s += 1; } return (r); } void lex_Init(void) { ULONG i; for (i = 0; i < LEXHASHSIZE; i += 1) { tLexHash[i] = NULL; } for (i = 0; i < 256; i += 1) { tFloatingFirstChar[i] = 0; tFloatingSecondChar[i] = 0; tFloatingChars[i] = 0; } nLexMaxLeng = 0; nFloating = 0; } void lex_AddStrings(struct sLexInitString * lex) { while (lex->tzName) { struct sLexString **ppHash; ULONG hash; ppHash = &tLexHash[hash = lexcalchash(lex->tzName)]; while (*ppHash) ppHash = &((*ppHash)->pNext); //printf("%s has hashvalue %d\n", lex->tzName, hash); if (((*ppHash) = (struct sLexString *) malloc(sizeof(struct sLexString))) != NULL) { if (((*ppHash)->tzName = (char *) strdup(lex->tzName)) != NULL) { (*ppHash)->nNameLength = strlen(lex->tzName); (*ppHash)->nToken = lex->nToken; (*ppHash)->pNext = NULL; strupr((*ppHash)->tzName); if ((*ppHash)->nNameLength > nLexMaxLeng) nLexMaxLeng = (*ppHash)->nNameLength; } else fatalerror("Out of memory!"); } else fatalerror("Out of memory!"); lex += 1; } } ULONG yylex(void) { ULONG hash, maxlen; char *s; struct sLexString *pLongestFixed = NULL; ULONG nFloatMask, nOldFloatMask, nFloatLen; ULONG linestart = AtLineStart; switch (lexerstate) { case LEX_STATE_NORMAL: AtLineStart = 0; scanagain: while (*pLexBuffer == ' ' || *pLexBuffer == '\t') { linestart = 0; pLexBuffer += 1; } if (*pLexBuffer == 0) { if (yywrap() == 0) { linestart = AtLineStart; AtLineStart = 0; goto scanagain; } } s = pLexBuffer; nOldFloatMask = nFloatLen = 0; nFloatMask = tFloatingFirstChar[(int) *s++]; while (nFloatMask && nFloatLen < nLexBufferLeng) { nFloatLen += 1; nOldFloatMask = nFloatMask; if (nFloatLen == 1) nFloatMask &= tFloatingSecondChar[(int) *s++]; else nFloatMask &= tFloatingChars[(int) *s++]; } maxlen = nLexBufferLeng; if (nLexMaxLeng < maxlen) maxlen = nLexMaxLeng; yyleng = 0; hash = 0; s = pLexBuffer; while (yyleng < nLexMaxLeng) { /* XXX: Kludge warning! The dereference of s below * may go beyond the end of the buffer. We use the * following test to stop that from happening, * without really understanding what the rest of * the code is doing. This may not be the correct * fix! */ if (!*s) break; yyleng += 1; hash = ((hash << 1) + (toupper(*s))) % LEXHASHSIZE; s += 1; if (tLexHash[hash]) { struct sLexString *lex; lex = tLexHash[hash]; while (lex) { if (lex->nNameLength == yyleng) { if (strncasecmp (pLexBuffer, lex->tzName, yyleng) == 0) { pLongestFixed = lex; } } lex = lex->pNext; } } } if (nFloatLen == 0 && pLongestFixed == NULL) { if (*pLexBuffer == '"') { ULONG index = 0; pLexBuffer += 1; while ((*pLexBuffer != '"') && (*pLexBuffer != '\n')) { char ch, *marg; if ((ch = *pLexBuffer++) == '\\') { switch (ch = (*pLexBuffer++)) { case 'n': ch = '\n'; break; case 't': ch = '\t'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((marg = sym_FindMacroArg(ch - '0')) != NULL) { while (*marg) yylval. tzString [index++] = *marg++; ch = 0; } break; case '@': if ((marg = sym_FindMacroArg (-1)) != NULL) { while (*marg) yylval. tzString [index++] = *marg++; ch = 0; } break; } } else if (ch == '{') { char sym[MAXSYMLEN]; int i = 0; while ((*pLexBuffer != '}') && (*pLexBuffer != '"') && (*pLexBuffer != '\n')) { if ((ch = *pLexBuffer++) == '\\') { switch (ch = (*pLexBuffer++)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((marg = sym_FindMacroArg(ch - '0')) != NULL) { while (*marg) sym[i++] = *marg++; ch = 0; } break; case '@': if ((marg = sym_FindMacroArg(-1)) != NULL) { while (*marg) sym[i++] = *marg++; ch = 0; } break; } } else sym[i++] = ch; } sym[i] = 0; index += symvaluetostring(&yylval. tzString [index], sym); if (*pLexBuffer == '}') pLexBuffer += 1; else yyerror("Missing }"); ch = 0; } if (ch) yylval.tzString[index++] = ch; } yylval.tzString[index++] = 0; if (*pLexBuffer == '\n') yyerror("Unterminated string"); else pLexBuffer += 1; return (T_STRING); } else if (*pLexBuffer == '{') { char sym[MAXSYMLEN], ch, *marg; int i = 0; pLexBuffer += 1; while ((*pLexBuffer != '}') && (*pLexBuffer != '\n')) { if ((ch = *pLexBuffer++) == '\\') { switch (ch = (*pLexBuffer++)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((marg = sym_FindMacroArg(ch - '0')) != NULL) { while (*marg) sym[i++] = *marg++; ch = 0; } break; case '@': if ((marg = sym_FindMacroArg (-1)) != NULL) { while (*marg) sym[i++] = *marg++; ch = 0; } break; } } else sym[i++] = ch; } sym[i] = 0; symvaluetostring(yylval.tzString, sym); if (*pLexBuffer == '}') pLexBuffer += 1; else yyerror("Missing }"); return (T_STRING); } else { if (*pLexBuffer == '\n') AtLineStart = 1; yyleng = 1; return (*pLexBuffer++); } } if (nFloatLen == 0) { yyleng = pLongestFixed->nNameLength; pLexBuffer += yyleng; return (pLongestFixed->nToken); } if (pLongestFixed == NULL) { struct sLexFloat *tok; tok = lexgetfloat(nOldFloatMask); yyleng = nFloatLen; if (tok->Callback) { if (tok->Callback(pLexBuffer, yyleng) == 0) goto scanagain; } if (tok->nToken == T_ID && linestart) { pLexBuffer += yyleng; return (T_LABEL); } else { pLexBuffer += yyleng; return (tok->nToken); } } if (nFloatLen > pLongestFixed->nNameLength) { struct sLexFloat *tok; tok = lexgetfloat(nOldFloatMask); yyleng = nFloatLen; if (tok->Callback) { if (tok->Callback(pLexBuffer, yyleng) == 0) goto scanagain; } if (tok->nToken == T_ID && linestart) { pLexBuffer += yyleng; return (T_LABEL); } else { pLexBuffer += yyleng; return (tok->nToken); } } else { yyleng = pLongestFixed->nNameLength; pLexBuffer += yyleng; return (pLongestFixed->nToken); } break; case LEX_STATE_MACROARGS: { ULONG index = 0; while (*pLexBuffer == ' ' || *pLexBuffer == '\t') { linestart = 0; pLexBuffer += 1; } while ((*pLexBuffer != ',') && (*pLexBuffer != '\n')) { char ch, *marg; if ((ch = *pLexBuffer++) == '\\') { switch (ch = (*pLexBuffer++)) { case 'n': ch = '\n'; break; case 't': ch = '\t'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((marg = sym_FindMacroArg(ch - '0')) != NULL) { while (*marg) yylval. tzString [index++] = *marg++; ch = 0; } break; case '@': if ((marg = sym_FindMacroArg(-1)) != NULL) { while (*marg) yylval. tzString [index++] = *marg++; ch = 0; } break; } } else if (ch == '{') { char sym[MAXSYMLEN]; int i = 0; while ((*pLexBuffer != '}') && (*pLexBuffer != '"') && (*pLexBuffer != '\n')) { if ((ch = *pLexBuffer++) == '\\') { switch (ch = (*pLexBuffer++)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((marg = sym_FindMacroArg (ch - '0')) != NULL) { while (*marg) sym[i++] = *marg++; ch = 0; } break; case '@': if ((marg = sym_FindMacroArg (-1)) != NULL) { while (*marg) sym[i++] = *marg++; ch = 0; } break; } } else sym[i++] = ch; } sym[i] = 0; index += symvaluetostring(&yylval. tzString[index], sym); if (*pLexBuffer == '}') pLexBuffer += 1; else yyerror("Missing }"); ch = 0; } if (ch) yylval.tzString[index++] = ch; } if (index) { yyleng = index; yylval.tzString[index] = 0; if (*pLexBuffer == '\n') { while (yylval.tzString[--index] == ' ') { yylval.tzString[index] = 0; yyleng -= 1; } } return (T_STRING); } else if (*pLexBuffer == '\n') { pLexBuffer += 1; AtLineStart = 1; yyleng = 1; return ('\n'); } else if (*pLexBuffer == ',') { pLexBuffer += 1; yyleng = 1; return (','); } else { yyerror("INTERNAL ERROR IN YYLEX"); return (0); } } break; } yyerror("INTERNAL ERROR IN YYLEX"); return (0); }