tge/engine/console/BASscan.l
2025-02-17 23:17:30 -06:00

290 lines
6.8 KiB
Plaintext
Executable File

%{
#define YYLMAX 4096
#include <stdio.h>
#include "platform/platform.h"
#include "core/stringTable.h"
#include "console/console.h"
#define _CMDGRAM_H_
#include "console/compiler.h"
#include "console/basgram.h"
using namespace Compiler;
#define YY_NEVER_INTERACTIVE 1
// Some basic parsing primitives...
static int Sc_ScanString(int ret);
static int Sc_ScanNum();
static int Sc_ScanVar();
static int Sc_ScanHex();
// Deal with debuggability of FLEX.
#ifdef TORQUE_DEBUG
#define FLEX_DEBUG 1
#else
#define FLEX_DEBUG 0
#endif
//#undef input
//#undef unput
#undef BASgetc
int BASgetc();
#define YY_INPUT(buf,result,max_size) \
{ \
int c = '*', n; \
for ( n = 0; n < max_size && \
(c = BASgetc()) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
if ( c == '\n' ) \
buf[n++] = (char) c; \
result = n; \
}
static int lineIndex;
// Prototypes
void BASSetScanBuffer(const char *sb, const char *fn);
void BASerror(char * s, ...);
// Error reporting
void CMDerror(char * s, ...);
// Reset the parser.
void CMDrestart(FILE *in);
%}
DIGIT [0-9]
INTEGER {DIGIT}+
FLOAT ({INTEGER}\.{INTEGER})|({INTEGER}(\.{INTEGER})?[eE][+-]?{INTEGER})
LETTER [A-Za-z_]
FILECHAR [A-Za-z_\.]
VARMID [:A-Za-z0-9_]
IDTAIL [A-Za-z0-9_]
VARTAIL {VARMID}*{IDTAIL}
VAR [$%]{LETTER}{VARTAIL}*
ID {LETTER}{IDTAIL}*
ILID [$%]{DIGIT}+{LETTER}{VARTAIL}*
FILENAME {FILECHAR}+
SPACE [ \t\v\f]
HEXDIGIT [a-fA-F0-9]
%%
;
{SPACE}+ { }
"//"[^\n\r]* ;
"rem"{SPACE}+[^\n\r]* ;
[\r] ;
[\n] { lineIndex++; }
\"(\\.|[^\\"\n\r])*\" { return(Sc_ScanString(STRATOM)); }
\'(\\.|[^\\'\n\r])*\' { return(Sc_ScanString(TAGATOM)); }
"==" return(BASlval.i = opEQ);
"!=" return(BASlval.i = opNE);
">=" return(BASlval.i = opGE);
"<=" return(BASlval.i = opLE);
"&&" return(BASlval.i = opAND);
"||" return(BASlval.i = opOR);
"::" return(BASlval.i = opCOLONCOLON);
"--" return(BASlval.i = opMINUSMINUS);
"++" return(BASlval.i = opPLUSPLUS);
"$=" return(BASlval.i = opSTREQ);
"!$=" return(BASlval.i = opSTRNE);
"<<" return(BASlval.i = opSHL);
">>" return(BASlval.i = opSHR);
"+=" return(BASlval.i = opPLASN);
"-=" return(BASlval.i = opMIASN);
"*=" return(BASlval.i = opMLASN);
"/=" return(BASlval.i = opDVASN);
"%=" return(BASlval.i = opMODASN);
"&=" return(BASlval.i = opANDASN);
"^=" return(BASlval.i = opXORASN);
"|=" return(BASlval.i = opORASN);
"<<=" return(BASlval.i = opSLASN);
">>=" return(BASlval.i = opSRASN);
"NL" {BASlval.i = '\n'; return '@'; }
"TAB" {BASlval.i = '\t'; return '@'; }
"SPC" {BASlval.i = ' '; return '@'; }
"@" {BASlval.i = 0; return '@'; }
"?" |
"[" |
"]" |
"(" |
")" |
"+" |
"-" |
"*" |
"/" |
"<" |
">" |
"|" |
"." |
"!" |
":" |
";" |
"{" |
"}" |
"," |
"&" |
"%" |
"^" |
"~" |
"=" { return(BASlval.i = BAStext[0]); }
"or" { BASlval.i = lineIndex; return(rwCASEOR); }
"break" { BASlval.i = lineIndex; return(rwBREAK); }
"return" { BASlval.i = lineIndex; return(rwRETURN); }
"else" { BASlval.i = lineIndex; return(rwELSE); }
"while" { BASlval.i = lineIndex; return(rwWHILE); }
"if" { BASlval.i = lineIndex; return(rwIF); }
"then" { BASlval.i = lineIndex; return(rwTHEN); }
"do" { BASlval.i = lineIndex; return(rwBEGIN); }
"begin" { BASlval.i = lineIndex; return(rwBEGIN); }
"end" { BASlval.i = lineIndex; return(rwEND); }
"for" { BASlval.i = lineIndex; return(rwFOR); }
"cfor" { BASlval.i = lineIndex; return(rwCFOR); }
"to" { BASlval.i = lineIndex; return(rwTO); }
"step" { BASlval.i = lineIndex; return(rwSTEP); }
"continue" { BASlval.i = lineIndex; return(rwCONTINUE); }
"function" { BASlval.i = lineIndex; return(rwDEFINE); }
"sub" { BASlval.i = lineIndex; return(rwDEFINE); }
"new" { BASlval.i = lineIndex; return(rwDECLARE); }
"datablock" { BASlval.i = lineIndex; return(rwDATABLOCK); }
"case" { BASlval.i = lineIndex; return(rwCASE); }
"switch$" { BASlval.i = lineIndex; return(rwSWITCHSTR); }
"switch" { BASlval.i = lineIndex; return(rwSWITCH); }
"default" { BASlval.i = lineIndex; return(rwDEFAULT); }
"package" { BASlval.i = lineIndex; return(rwPACKAGE); }
"true" { BASlval.i = 1; return INTCONST; }
"false" { BASlval.i = 0; return INTCONST; }
{VAR} return(Sc_ScanVar());
{ID} { BAStext[BASleng] = 0; BASlval.s = StringTable->insert(BAStext); return(IDENT); }
0[xX]{HEXDIGIT}+ return(Sc_ScanHex());
{INTEGER} { BAStext[BASleng] = 0; BASlval.i = atoi(BAStext); return INTCONST; }
{FLOAT} return Sc_ScanNum();
{ILID} return(ILLEGAL_TOKEN);
. return(ILLEGAL_TOKEN);
%%
/*
* Scan character constant.
*/
/*
* Scan identifier.
*/
static const char *scanBuffer;
static const char *fileName;
static int scanIndex;
const char * BASGetCurrentFile()
{
return fileName;
}
int BASGetCurrentLine()
{
return lineIndex;
}
void BASerror(char *, ...)
{
gSyntaxError = true;
if(fileName)
Con::errorf(ConsoleLogEntry::Script, "%s Line: %d - Syntax error.",
fileName, lineIndex);
else
Con::errorf(ConsoleLogEntry::Script, "Syntax error in input.");
}
void BASSetScanBuffer(const char *sb, const char *fn)
{
scanBuffer = sb;
fileName = fn;
scanIndex = 0;
lineIndex = 1;
}
int BASgetc()
{
int ret = scanBuffer[scanIndex];
if(ret)
scanIndex++;
else
ret = -1;
return ret;
}
int BASwrap()
{
return 1;
}
static int Sc_ScanVar()
{
BAStext[BASleng] = 0;
BASlval.s = StringTable->insert(BAStext);
return(VAR);
}
/*
* Scan string constant.
*/
// Defined in CS_CMD.l
extern void expandEscape(char *dest, const char *src);
extern bool collapseEscape(char *buf);
static int charConv(int in)
{
switch(in)
{
case 'r':
return '\r';
case 'n':
return '\n';
case 't':
return '\t';
default:
return in;
}
}
static int getHexDigit(char c)
{
if(c >= '0' && c <= '9')
return c - '0';
if(c >= 'A' && c <= 'F')
return c - 'A' + 10;
if(c >= 'a' && c <= 'f')
return c - 'a' + 10;
return -1;
}
static int Sc_ScanString(int ret)
{
BAStext[BASleng - 1] = 0;
if(!collapseEscape(BAStext+1))
return -1;
BASlval.str = (char *) consoleAlloc(dStrlen(BAStext));
dStrcpy(BASlval.str, BAStext + 1);
return(ret);
}
static int Sc_ScanNum()
{
BAStext[BASleng] = 0;
BASlval.f = atof(BAStext);
return(FLTCONST);
}
static int Sc_ScanHex()
{
int val = 0;
dSscanf(BAStext, "%x", &val);
BASlval.i = val;
return INTCONST;
}