mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 21:41:03 +00:00
43abfba723
re2c instead of "Linking X". - Updated lemon and re2c to the latest versions and ported dehsupp to use them for code generation. (Xlatcc is next.) - Added function level linking for Makefile.mingw. SVN r144 (trunk)
176 lines
3.4 KiB
C++
176 lines
3.4 KiB
C++
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <stdlib.h>
|
|
#include "dehsupp.h"
|
|
|
|
#define BSIZE 8192
|
|
|
|
#define YYCTYPE uchar
|
|
#define YYCURSOR cursor
|
|
#define YYLIMIT s->lim
|
|
#define YYMARKER s->ptr
|
|
#define YYFILL(n) {cursor = fill(s, cursor);}
|
|
|
|
#define RET(i) {s->cur = cursor; return i;}
|
|
|
|
uchar *fill(Scanner *s, uchar *cursor)
|
|
{
|
|
if(!s->eof)
|
|
{
|
|
ptrdiff_t cnt = s->tok - s->bot;
|
|
if(cnt)
|
|
{
|
|
memcpy(s->bot, s->tok, s->lim - s->tok);
|
|
s->tok = s->bot;
|
|
s->ptr -= cnt;
|
|
cursor -= cnt;
|
|
s->pos -= cnt;
|
|
s->lim -= cnt;
|
|
}
|
|
if((s->top - s->lim) < BSIZE)
|
|
{
|
|
uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
|
|
memcpy(buf, s->tok, s->lim - s->tok);
|
|
s->tok = buf;
|
|
s->ptr = &buf[s->ptr - s->bot];
|
|
cursor = &buf[cursor - s->bot];
|
|
s->pos = &buf[s->pos - s->bot];
|
|
s->lim = &buf[s->lim - s->bot];
|
|
s->top = &s->lim[BSIZE];
|
|
free(s->bot);
|
|
s->bot = buf;
|
|
}
|
|
if((cnt = fread((char*) s->lim, 1, BSIZE, s->fd)) != BSIZE)
|
|
{
|
|
s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
|
|
}
|
|
s->lim += cnt;
|
|
}
|
|
return cursor;
|
|
}
|
|
|
|
int scan(Scanner *s)
|
|
{
|
|
uchar *cursor = s->cur;
|
|
std:
|
|
s->tok = cursor;
|
|
/*!re2c
|
|
any = [\000-\377];
|
|
O = [0-7];
|
|
D = [0-9];
|
|
L = [a-zA-Z_];
|
|
H = [a-fA-F0-9];
|
|
ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
|
|
*/
|
|
|
|
/*!re2c
|
|
"/*" { goto comment; } /* C comment */
|
|
"//" (any\"\n")* "\n" /* C++ comment */
|
|
{
|
|
if(cursor == s->eof) RET(EOI);
|
|
s->tok = s->pos = cursor; s->line++;
|
|
goto std;
|
|
}
|
|
|
|
"endl" { RET(ENDL); }
|
|
"print" { RET(PRINT); }
|
|
"Actions" { RET(Actions); }
|
|
"OrgHeights" { RET(OrgHeights); }
|
|
"ActionList" { RET(ActionList); }
|
|
"CodePConv" { RET(CodePConv); }
|
|
"OrgSprNames" { RET(OrgSprNames); }
|
|
"StateMap" { RET(StateMap); }
|
|
"SoundMap" { RET(SoundMap); }
|
|
"InfoNames" { RET(InfoNames); }
|
|
"ThingBits" { RET(ThingBits); }
|
|
"DeathState" { RET(DeathState); }
|
|
"SpawnState" { RET(SpawnState); }
|
|
"FirstState" { RET(FirstState); }
|
|
"RenderStyles" { RET(RenderStyles); }
|
|
|
|
L (L|D)* { RET(SYM); }
|
|
|
|
("0" [xX] H+) | ("0" D+) | (D+)
|
|
{ RET(NUM); }
|
|
|
|
(["] (ESC|any\[\n\\"])* ["])
|
|
{ RET(STRING); }
|
|
|
|
[ \t\v\f]+ { goto std; }
|
|
|
|
"|" { RET(OR); }
|
|
"^" { RET(XOR); }
|
|
"&" { RET(AND); }
|
|
"-" { RET(MINUS); }
|
|
"+" { RET(PLUS); }
|
|
"*" { RET(MULTIPLY); }
|
|
"/" { RET(DIVIDE); }
|
|
"(" { RET(LPAREN); }
|
|
"}" { RET(RPAREN); }
|
|
"," { RET(COMMA); }
|
|
"{" { RET(LBRACE); }
|
|
"}" { RET(RBRACE); }
|
|
";" { RET(SEMICOLON); }
|
|
|
|
|
|
"\n"
|
|
{
|
|
if(cursor == s->eof) RET(EOI);
|
|
s->pos = cursor; s->line++;
|
|
goto std;
|
|
}
|
|
|
|
any
|
|
{
|
|
printf("unexpected character: %c\n", *s->tok);
|
|
goto std;
|
|
}
|
|
*/
|
|
|
|
comment:
|
|
/*!re2c
|
|
"*/" { goto std; }
|
|
"\n"
|
|
{
|
|
if(cursor == s->eof) RET(EOI);
|
|
s->tok = s->pos = cursor; s->line++;
|
|
goto comment;
|
|
}
|
|
any { goto comment; }
|
|
*/
|
|
}
|
|
|
|
int lex(Scanner *s, struct Token *tok)
|
|
{
|
|
int tokentype = scan(s);
|
|
char *p, *q;
|
|
|
|
tok->val = 0;
|
|
tok->string = NULL;
|
|
|
|
switch (tokentype)
|
|
{
|
|
case NUM:
|
|
tok->val = strtol((char *)s->tok, NULL, 0);
|
|
break;
|
|
|
|
case STRING:
|
|
tok->string = (char *)malloc(s->cur - s->tok - 1);
|
|
strncpy(tok->string, (char *)s->tok + 1, s->cur - s->tok - 2);
|
|
tok->string[s->cur - s->tok - 2] = '\0';
|
|
for (p = q = tok->string; *p; ++p, ++q)
|
|
{
|
|
if (p[0] == '\\' && p[1] == '\\')
|
|
++p;
|
|
*q = *p;
|
|
}
|
|
break;
|
|
|
|
case SYM:
|
|
tok->string = (char *)malloc(s->cur - s->tok + 1);
|
|
strncpy(tok->string, (char *)s->tok, s->cur - s->tok);
|
|
tok->string[s->cur - s->tok] = '\0';
|
|
break;
|
|
}
|
|
return tokentype;
|
|
}
|