📄 chsscan.l
字号:
%{
#define YYLMAX 4096
#include <stdio.h>
#include "platform/platform.h"
#include "core/stringTable.h"
#include "console/console.h"
#include "console/macroManager.h"
#define _CMDGRAM_H_
#include "console/compiler.h"
#include "console/chsgram.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();
static void Sc_RegisterMacro(int nBase,bool bMacro=true);
static StringTableEntry Sc_FindMacro(StringTableEntry pName);
// Deal with debuggability of FLEX.
#ifdef TORQUE_DEBUG
#define FLEX_DEBUG 1
#else
#define FLEX_DEBUG 0
#endif
// Install our own input code...
#undef CHSgetc
int CHSgetc();
// Hack to make windows lex happy.
#ifndef isatty
inline int isatty(int) { return 0; }
#endif
// Wrap our getc, so that lex doesn't try to do its own buffering/file IO.
#define YY_INPUT(buf,result,max_size) \
{ \
int c = '*', n; \
for ( n = 0; n < max_size && \
(c = CHSgetc()) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
if ( c == '\n' ) \
buf[n++] = (char) c; \
result = n; \
}
// General helper stuff.
static int lineIndex;
// File state
void CHSSetScanBuffer(const char *sb, const char *fn);
const char * CHSgetFileLine(int &lineNumber);
// Error reporting
void CHSerror(char * s, ...);
// Reset the parser.
void CHSrestart(FILE *in);
%}
/*
Float 0.0 0e0 0.0e0 0e+0
.0 0.
*/
DIGIT [0-9]
ALPHA [A-Za-z_]
HEXDIGIT [a-fA-F0-9]
SPACE [ \t\v\f]
FILECHAR [A-Za-z_\.]
ALPHANUM [A-Za-z0-9_]
GB2312 [\xa1-\xf6]
CN_WORD {GB2312}{2}
CN_ALPHA {ALPHA}|{CN_WORD}
CN_ALPHANUM {ALPHANUM}|{CN_WORD}
VARMID ({CN_ALPHANUM})|(:)
INTEGER {DIGIT}+
INTEGER0 {DIGIT}*
FLOAT_E ({INTEGER}(\.{INTEGER})?[eE][+-]?{INTEGER})
FLOAT_N ({INTEGER}\.{INTEGER})|({INTEGER}\.)|(\.{INTEGER})
FLOAT {FLOAT_E}|{FLOAT_N}
HEXNUM 0[xX]{HEXDIGIT}+
VARTAIL {VARMID}*{CN_ALPHANUM}
VAR [$%]{CN_ALPHA}{VARTAIL}*
ID {CN_ALPHA}{CN_ALPHANUM}*
ILID [$%]{DIGIT}+{CN_ALPHA}{VARTAIL}*
FILENAME {FILECHAR}+
STRING \"(\\.|[^\\\"\n\r])*\"
STRTAG \'(\\.|[^\\\'\n\r])*\'
MSTRING \"(\\.|[^\\\"])*\"
VSTRING "V"{MSTRING}
MACRO_V {STRING}|{STRTAG}|{FLOAT}|{VAR}|{ID}|{FILENAME}|{INTEGER}|{HEXNUM}
MACRO_N {VAR}|{ID}
MACRO "#macro"{SPACE}+{MACRO_N}{SPACE}+{MACRO_V}{SPACE}*[;]+
MACRO0 "#macro"{SPACE}+{MACRO_N}{SPACE}*[;]+
UNMACRO "#unmacro"{SPACE}+{MACRO_N}{SPACE}*[;]+
%x commentBlock
%%
;
{SPACE}+ {}
{MACRO} {Sc_RegisterMacro(sizeof("#macro ")-1,true);}
{MACRO0} {Sc_RegisterMacro(sizeof("#macro ")-1,false);}
{UNMACRO} {Sc_RegisterMacro(sizeof("#unmacro ")-1,false);}
"//"[^\n\r]* ;
[\r] ;
[\n] {lineIndex++;}
{VSTRING} { return(Sc_ScanString(VSTR)); }
{STRING} { return(Sc_ScanString(STRATOM)); }
{STRTAG} { return(Sc_ScanString(TAGATOM)); }
"===" return(CHSlval.i = opSTREQ);
"!==" return(CHSlval.i = opSTRNE);
"$=" return(CHSlval.i = opSTREQ);
"!$=" return(CHSlval.i = opSTRNE);
"==" return(CHSlval.i = opEQ);
"!=" return(CHSlval.i = opNE);
">=" return(CHSlval.i = opGE);
"<=" return(CHSlval.i = opLE);
"&&" return(CHSlval.i = opAND);
"||" return(CHSlval.i = opOR);
"::" return(CHSlval.i = opCOLONCOLON);
"--" return(CHSlval.i = opMINUSMINUS);
"++" return(CHSlval.i = opPLUSPLUS);
"<<" return(CHSlval.i = opSHL);
">>" return(CHSlval.i = opSHR);
"+=" return(CHSlval.i = opPLASN);
"-=" return(CHSlval.i = opMIASN);
"*=" return(CHSlval.i = opMLASN);
"/=" return(CHSlval.i = opDVASN);
"%=" return(CHSlval.i = opMODASN);
"&=" return(CHSlval.i = opANDASN);
"^=" return(CHSlval.i = opXORASN);
"|=" return(CHSlval.i = opORASN);
"<<=" return(CHSlval.i = opSLASN);
">>=" return(CHSlval.i = opSRASN);
"->" return(CHSlval.i = opOBJPTR);
"NL" {CHSlval.i = '\n'; return '@'; }
"TAB" {CHSlval.i = '\t'; return '@'; }
"SPC" {CHSlval.i = ' '; return '@'; }
"@" {CHSlval.i = 0; return '@'; }
"/*" BEGIN(commentBlock);
<commentBlock>[^*\n]*
<commentBlock>[^*\n]*\n {++lineIndex;}
<commentBlock>"*"+[^*/\n]*
<commentBlock>"*"+[^*/\n]*\n {++lineIndex;}
<commentBlock>"*"+"/" {BEGIN(0);}
"?" |
"[" |
"]" |
"(" |
")" |
"+" |
"-" |
"*" |
"/" |
"<" |
">" |
"|" |
"." |
"!" |
":" |
";" |
"{" |
"}" |
"," |
"&" |
"%" |
"^" |
"~" |
"=" { return(CHSlval.i = CHStext[0]); }
"var" {}
"or" { CHSlval.i = lineIndex; return(rwCASEOR); }
"break" { CHSlval.i = lineIndex; return(rwBREAK); }
"return" { CHSlval.i = lineIndex; return(rwRETURN); }
"else" { CHSlval.i = lineIndex; return(rwELSE); }
"while" { CHSlval.i = lineIndex; return(rwWHILE); }
"do" { CHSlval.i = lineIndex; return(rwDO); }
"if" { CHSlval.i = lineIndex; return(rwIF); }
"for" { CHSlval.i = lineIndex; return(rwFOR); }
"continue" { CHSlval.i = lineIndex; return(rwCONTINUE); }
"function" { CHSlval.i = lineIndex; return(rwDEFINE); }
"new" { CHSlval.i = lineIndex; return(rwDECLARE); }
"datablock" { CHSlval.i = lineIndex; return(rwDATABLOCK); }
"case" { CHSlval.i = lineIndex; return(rwCASE); }
"switch$" { CHSlval.i = lineIndex; return(rwSWITCHSTR); }
"switch" { CHSlval.i = lineIndex; return(rwSWITCH); }
"default" { CHSlval.i = lineIndex; return(rwDEFAULT); }
"package" { CHSlval.i = lineIndex; return(rwPACKAGE); }
"namespace" { CHSlval.i = lineIndex; return(rwNAMESPACE); }
"true" { CHSlval.i = 1; return INTCONST; }
"false" { CHSlval.i = 0; return INTCONST; }
"null" { CHSlval.i = 0; return INTCONST; }
"blank" { CHSlval.str = (char*)consoleAlloc(1);CHSlval.str[0] =0; return STRATOM; }
{VAR} {if(Sc_ScanVar())return (VAR);}
{ID} {if(Sc_ScanVar())return (IDENT); }
{HEXNUM} return(Sc_ScanHex());
{INTEGER} { CHStext[CHSleng] = 0; CHSlval.i = dAtoi(CHStext); return INTCONST; }
{FLOAT} return Sc_ScanNum();
{ILID} return(ILLEGAL_TOKEN);
. return(ILLEGAL_TOKEN);
%%
static const char *scanBuffer;
static const char *fileName;
static int scanIndex;
const char * CHSGetCurrentFile()
{
return fileName;
}
int CHSGetCurrentLine()
{
return lineIndex;
}
void CHSerror(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 CHSSetScanBuffer(const char *sb, const char *fn)
{
scanBuffer = sb;
fileName = fn;
scanIndex = 0;
lineIndex = 1;
}
int CHSgetc()
{
int ret = scanBuffer[scanIndex];
if(ret)
scanIndex++;
else
ret = -1;
return ret;
}
int CHSwrap()
{
return 1;
}
static int Sc_ScanVar()
{
// Truncate the temp buffer...
CHStext[CHSleng] = 0;
StringTableEntry pText = StringTable->insert(CHStext);
StringTableEntry pMacro = Sc_FindMacro(pText);
if(pMacro == pText)
{
// Make it a stringtable string!
CHSlval.s = pText;
return(true);
}
//把macro内容放到缓存头即可
// yyless(0);
U32 nLen = dStrlen(pMacro);
for(S32 n=nLen-1; n >=0; n--)
unput(pMacro[n]);
return false;
}
// 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)
{
CHStext[CHSleng - 1] = 0;
if(!collapseEscape(CHStext+1))
return -1;
CHSlval.str = (char *) consoleAlloc(dStrlen(CHStext));
dStrcpy(CHSlval.str, CHStext + (ret==VSTR?2:1));
return(ret);
}
static int Sc_ScanNum()
{
CHStext[CHSleng] = 0;
CHSlval.f = dAtof(CHStext);
return(FLTCONST);
}
static int Sc_ScanHex()
{
S32 val = 0;
dSscanf(CHStext, "%x", &val);
CHSlval.i = val;
return INTCONST;
}
static void Sc_RegisterMacro(int nBase,bool bMacro)
{
//#macro abc 123
++lineIndex;
///扫描Name
U32 n,m;
CHStext[CHSleng] = 0;
for(n=nBase;;n++)
if(!dIsspace(CHStext[n]))
break;
for(m=n;m<CHSleng;m++)
if(dIsspace(CHStext[m]) || CHStext[m]==';')
break;
CHStext[m] = 0;
StringTableEntry pName = StringTable->insert(CHStext+n);
if(bMacro==false)
{
gMacroDictionary.remove(pName);
return;
}
gMacroDictionary.begin(pName);
//扫描Value
for(n=m+1;;n++)
if(!dIsspace(CHStext[n]))
break;
//中间是字符串、Tag时,可能会出现空格,故从尾部倒回来扫描
// for(m=n;m<CHSleng;m++)
for(m=CHSleng-1;m > n;m--)
if(!dIsspace(CHStext[m]) && CHStext[m]!=';')
break;
CHStext[m+1] = 0;
StringTableEntry pValue = StringTable->insert(CHStext+n);
gMacroDictionary.end(pValue);
}
static StringTableEntry Sc_FindMacro(StringTableEntry pName)
{
StringTableEntry pField = gMacroDictionary.find(pName);
if(pField != 0)
return pField;
return pName;
}
void CHS_reset()
{
CHSrestart(NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -