Merge pull request #100 from mawww/scanner-optim

Scanner optimisations
This commit is contained in:
John Kessenich 2015-12-06 17:12:53 -07:00
commit 71e04d62a4
2 changed files with 80 additions and 57 deletions

View File

@ -293,10 +293,33 @@ int yylex(YYSTYPE* glslangTokenDesc, glslang::TParseContext& parseContext)
namespace { namespace {
struct str_eq
{
bool operator()(const char* lhs, const char* rhs) const
{
return strcmp(lhs, rhs) == 0;
}
};
struct str_hash
{
size_t operator()(const char* str) const
{
// djb2
unsigned long hash = 5381;
int c;
while (c = *str++)
hash = ((hash << 5) + hash) + c;
return hash;
}
};
// A single global usable by all threads, by all versions, by all languages. // A single global usable by all threads, by all versions, by all languages.
// After a single process-level initialization, this is read only and thread safe // After a single process-level initialization, this is read only and thread safe
std::unordered_map<std::string, int>* KeywordMap = nullptr; std::unordered_map<const char*, int, str_hash, str_eq>* KeywordMap = nullptr;
std::unordered_set<std::string>* ReservedSet = nullptr; std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
}; };
@ -309,7 +332,7 @@ void TScanContext::fillInKeywordMap()
// but, the only risk is if two threads called simultaneously // but, the only risk is if two threads called simultaneously
return; return;
} }
KeywordMap = new std::unordered_map<std::string, int>; KeywordMap = new std::unordered_map<const char*, int, str_hash, str_eq>;
(*KeywordMap)["const"] = CONST; (*KeywordMap)["const"] = CONST;
(*KeywordMap)["uniform"] = UNIFORM; (*KeywordMap)["uniform"] = UNIFORM;
@ -481,7 +504,7 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["resource"] = RESOURCE; (*KeywordMap)["resource"] = RESOURCE;
(*KeywordMap)["superp"] = SUPERP; (*KeywordMap)["superp"] = SUPERP;
ReservedSet = new std::unordered_set<std::string>; ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
ReservedSet->insert("common"); ReservedSet->insert("common");
ReservedSet->insert("partition"); ReservedSet->insert("partition");

View File

@ -242,11 +242,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ppToken->ival = 0; ppToken->ival = 0;
ppToken->space = false; ppToken->space = false;
ch = pp->getChar(); ch = getch();
for (;;) { for (;;) {
while (ch == ' ' || ch == '\t') { while (ch == ' ' || ch == '\t') {
ppToken->space = true; ppToken->space = true;
ch = pp->getChar(); ch = getch();
} }
ppToken->loc = pp->parseContext.getCurrentLoc(); ppToken->loc = pp->parseContext.getCurrentLoc();
@ -271,13 +271,13 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
do { do {
if (len < MaxTokenLength) { if (len < MaxTokenLength) {
tokenText[len++] = (char)ch; tokenText[len++] = (char)ch;
ch = pp->getChar(); ch = getch();
} else { } else {
if (! AlreadyComplained) { if (! AlreadyComplained) {
pp->parseContext.ppError(ppToken->loc, "name too long", "", ""); pp->parseContext.ppError(ppToken->loc, "name too long", "", "");
AlreadyComplained = 1; AlreadyComplained = 1;
} }
ch = pp->getChar(); ch = getch();
} }
} while ((ch >= 'a' && ch <= 'z') || } while ((ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') || (ch >= 'A' && ch <= 'Z') ||
@ -289,18 +289,18 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
continue; continue;
tokenText[len] = '\0'; tokenText[len] = '\0';
pp->ungetChar(); ungetch();
ppToken->atom = pp->LookUpAddString(tokenText); ppToken->atom = pp->LookUpAddString(tokenText);
return PpAtomIdentifier; return PpAtomIdentifier;
case '0': case '0':
ppToken->name[len++] = (char)ch; ppToken->name[len++] = (char)ch;
ch = pp->getChar(); ch = getch();
if (ch == 'x' || ch == 'X') { if (ch == 'x' || ch == 'X') {
// must be hexidecimal // must be hexidecimal
bool isUnsigned = false; bool isUnsigned = false;
ppToken->name[len++] = (char)ch; ppToken->name[len++] = (char)ch;
ch = pp->getChar(); ch = getch();
if ((ch >= '0' && ch <= '9') || if ((ch >= '0' && ch <= '9') ||
(ch >= 'A' && ch <= 'F') || (ch >= 'A' && ch <= 'F') ||
(ch >= 'a' && ch <= 'f')) { (ch >= 'a' && ch <= 'f')) {
@ -325,7 +325,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
} }
ival = 0xffffffff; ival = 0xffffffff;
} }
ch = pp->getChar(); ch = getch();
} while ((ch >= '0' && ch <= '9') || } while ((ch >= '0' && ch <= '9') ||
(ch >= 'A' && ch <= 'F') || (ch >= 'A' && ch <= 'F') ||
(ch >= 'a' && ch <= 'f')); (ch >= 'a' && ch <= 'f'));
@ -337,7 +337,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ppToken->name[len++] = (char)ch; ppToken->name[len++] = (char)ch;
isUnsigned = true; isUnsigned = true;
} else } else
pp->ungetChar(); ungetch();
ppToken->name[len] = '\0'; ppToken->name[len] = '\0';
ppToken->ival = (int)ival; ppToken->ival = (int)ival;
@ -366,7 +366,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ival = (ival << 3) | ii; ival = (ival << 3) | ii;
} else } else
octalOverflow = true; octalOverflow = true;
ch = pp->getChar(); ch = getch();
} }
// could be part of a float... // could be part of a float...
@ -379,7 +379,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", ""); pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
AlreadyComplained = 1; AlreadyComplained = 1;
} }
ch = pp->getChar(); ch = getch();
} while (ch >= '0' && ch <= '9'); } while (ch >= '0' && ch <= '9');
} }
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L')
@ -394,7 +394,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ppToken->name[len++] = (char)ch; ppToken->name[len++] = (char)ch;
isUnsigned = true; isUnsigned = true;
} else } else
pp->ungetChar(); ungetch();
ppToken->name[len] = '\0'; ppToken->name[len] = '\0';
if (octalOverflow) if (octalOverflow)
@ -419,7 +419,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", ""); pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
AlreadyComplained = 1; AlreadyComplained = 1;
} }
ch = pp->getChar(); ch = getch();
} while (ch >= '0' && ch <= '9'); } while (ch >= '0' && ch <= '9');
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') { if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') {
return pp->lFloatConst(len, ch, ppToken); return pp->lFloatConst(len, ch, ppToken);
@ -432,7 +432,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ppToken->name[len++] = (char)ch; ppToken->name[len++] = (char)ch;
uint = true; uint = true;
} else } else
pp->ungetChar(); ungetch();
ppToken->name[len] = '\0'; ppToken->name[len] = '\0';
ival = 0; ival = 0;
@ -456,153 +456,153 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
} }
break; break;
case '-': case '-':
ch = pp->getChar(); ch = getch();
if (ch == '-') { if (ch == '-') {
return PpAtomDecrement; return PpAtomDecrement;
} else if (ch == '=') { } else if (ch == '=') {
return PpAtomSub; return PpAtomSub;
} else { } else {
pp->ungetChar(); ungetch();
return '-'; return '-';
} }
case '+': case '+':
ch = pp->getChar(); ch = getch();
if (ch == '+') { if (ch == '+') {
return PpAtomIncrement; return PpAtomIncrement;
} else if (ch == '=') { } else if (ch == '=') {
return PpAtomAdd; return PpAtomAdd;
} else { } else {
pp->ungetChar(); ungetch();
return '+'; return '+';
} }
case '*': case '*':
ch = pp->getChar(); ch = getch();
if (ch == '=') { if (ch == '=') {
return PpAtomMul; return PpAtomMul;
} else { } else {
pp->ungetChar(); ungetch();
return '*'; return '*';
} }
case '%': case '%':
ch = pp->getChar(); ch = getch();
if (ch == '=') { if (ch == '=') {
return PpAtomMod; return PpAtomMod;
} else { } else {
pp->ungetChar(); ungetch();
return '%'; return '%';
} }
case '^': case '^':
ch = pp->getChar(); ch = getch();
if (ch == '^') { if (ch == '^') {
return PpAtomXor; return PpAtomXor;
} else { } else {
if (ch == '=') if (ch == '=')
return PpAtomXorAssign; return PpAtomXorAssign;
else{ else{
pp->ungetChar(); ungetch();
return '^'; return '^';
} }
} }
case '=': case '=':
ch = pp->getChar(); ch = getch();
if (ch == '=') { if (ch == '=') {
return PpAtomEQ; return PpAtomEQ;
} else { } else {
pp->ungetChar(); ungetch();
return '='; return '=';
} }
case '!': case '!':
ch = pp->getChar(); ch = getch();
if (ch == '=') { if (ch == '=') {
return PpAtomNE; return PpAtomNE;
} else { } else {
pp->ungetChar(); ungetch();
return '!'; return '!';
} }
case '|': case '|':
ch = pp->getChar(); ch = getch();
if (ch == '|') { if (ch == '|') {
return PpAtomOr; return PpAtomOr;
} else if (ch == '=') { } else if (ch == '=') {
return PpAtomOrAssign; return PpAtomOrAssign;
} else { } else {
pp->ungetChar(); ungetch();
return '|'; return '|';
} }
case '&': case '&':
ch = pp->getChar(); ch = getch();
if (ch == '&') { if (ch == '&') {
return PpAtomAnd; return PpAtomAnd;
} else if (ch == '=') { } else if (ch == '=') {
return PpAtomAndAssign; return PpAtomAndAssign;
} else { } else {
pp->ungetChar(); ungetch();
return '&'; return '&';
} }
case '<': case '<':
ch = pp->getChar(); ch = getch();
if (ch == '<') { if (ch == '<') {
ch = pp->getChar(); ch = getch();
if (ch == '=') if (ch == '=')
return PpAtomLeftAssign; return PpAtomLeftAssign;
else { else {
pp->ungetChar(); ungetch();
return PpAtomLeft; return PpAtomLeft;
} }
} else if (ch == '=') { } else if (ch == '=') {
return PpAtomLE; return PpAtomLE;
} else { } else {
pp->ungetChar(); ungetch();
return '<'; return '<';
} }
case '>': case '>':
ch = pp->getChar(); ch = getch();
if (ch == '>') { if (ch == '>') {
ch = pp->getChar(); ch = getch();
if (ch == '=') if (ch == '=')
return PpAtomRightAssign; return PpAtomRightAssign;
else { else {
pp->ungetChar(); ungetch();
return PpAtomRight; return PpAtomRight;
} }
} else if (ch == '=') { } else if (ch == '=') {
return PpAtomGE; return PpAtomGE;
} else { } else {
pp->ungetChar(); ungetch();
return '>'; return '>';
} }
case '.': case '.':
ch = pp->getChar(); ch = getch();
if (ch >= '0' && ch <= '9') { if (ch >= '0' && ch <= '9') {
pp->ungetChar(); ungetch();
return pp->lFloatConst(0, '.', ppToken); return pp->lFloatConst(0, '.', ppToken);
} else { } else {
pp->ungetChar(); ungetch();
return '.'; return '.';
} }
case '/': case '/':
ch = pp->getChar(); ch = getch();
if (ch == '/') { if (ch == '/') {
pp->inComment = true; pp->inComment = true;
do { do {
ch = pp->getChar(); ch = getch();
} while (ch != '\n' && ch != EndOfInput); } while (ch != '\n' && ch != EndOfInput);
ppToken->space = true; ppToken->space = true;
pp->inComment = false; pp->inComment = false;
return ch; return ch;
} else if (ch == '*') { } else if (ch == '*') {
ch = pp->getChar(); ch = getch();
do { do {
while (ch != '*') { while (ch != '*') {
if (ch == EndOfInput) { if (ch == EndOfInput) {
pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", ""); pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", "");
return ch; return ch;
} }
ch = pp->getChar(); ch = getch();
} }
ch = pp->getChar(); ch = getch();
if (ch == EndOfInput) { if (ch == EndOfInput) {
pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", ""); pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", "");
return ch; return ch;
@ -614,29 +614,29 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
} else if (ch == '=') { } else if (ch == '=') {
return PpAtomDiv; return PpAtomDiv;
} else { } else {
pp->ungetChar(); ungetch();
return '/'; return '/';
} }
break; break;
case '"': case '"':
ch = pp->getChar(); ch = getch();
while (ch != '"' && ch != '\n' && ch != EndOfInput) { while (ch != '"' && ch != '\n' && ch != EndOfInput) {
if (len < MaxTokenLength) { if (len < MaxTokenLength) {
tokenText[len] = (char)ch; tokenText[len] = (char)ch;
len++; len++;
ch = pp->getChar(); ch = getch();
} else } else
break; break;
}; };
tokenText[len] = '\0'; tokenText[len] = '\0';
if (ch != '"') { if (ch != '"') {
pp->ungetChar(); ungetch();
pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", ""); pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
} }
return PpAtomConstString; return PpAtomConstString;
} }
ch = pp->getChar(); ch = getch();
} }
} }