-
-
Save BradleyChatha/873077996b36c9f575fa2410e03705d5 to your computer and use it in GitHub Desktop.
D Bugzilla Report Code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Causes the compiler to hang for several minutes. | |
module lexer; | |
struct Token | |
{ | |
static struct Operator { string symbol; } | |
enum Type | |
{ | |
@(Token.Operator("/")) operatorSlash, | |
@(Token.Operator("/=")) operatorSlashEqual, | |
@(Token.Operator("&")) operatorAnd, | |
@(Token.Operator("&=")) operatorAndEqual, | |
@(Token.Operator("&&")) operatorAndAnd, | |
@(Token.Operator("?")) operatorQuestion, | |
@(Token.Operator("$")) operatorDollar, | |
@(Token.Operator("=")) operatorEqual, | |
@(Token.Operator("==")) operatorEqualEqual, | |
@(Token.Operator("*")) operatorStar, | |
@(Token.Operator("*=")) operatorStartEqual, | |
} | |
} | |
struct Lexer | |
{ | |
private | |
{ | |
string _sourceName; | |
string _input; | |
size_t _index; | |
} | |
@safe: | |
Token nextOperator() | |
{ | |
const ch = this.safePeek(); | |
Token token; | |
const couldLex = nextVaryingLengthToken!( | |
safePeek, | |
Token.Operator | |
)(token); | |
return token; | |
} | |
// Complex reading // | |
bool nextVaryingLengthToken(alias ReadFunc, alias UdaT)(scope out Token outToken) | |
{ | |
import std.algorithm : startsWith; | |
import std.traits : getUDAs, getSymbolsByUDA; | |
alias TokenTypes = getSymbolsByUDA!(Token.Type, UdaT); | |
enum TokenSymbolFor(alias TokenType) = getUDAs!(TokenType, UdaT)[0].symbol; | |
bool tryLexLongerOperators(alias TokenType)() | |
{ | |
static if(is(TokenType == noreturn)) | |
const NextSymbolStartSlice = ""; | |
else | |
const NextSymbolStartSlice = TokenSymbolFor!TokenType; | |
const ch = this.safePeek(); | |
switch(ch) | |
{ | |
static foreach(type; TokenTypes) | |
{ | |
static if( | |
TokenSymbolFor!type.length == NextSymbolStartSlice.length+1 | |
&& TokenSymbolFor!type.startsWith(NextSymbolStartSlice) | |
) | |
case TokenSymbolFor!type[$-1]: | |
this.eat(); | |
if(tryLexLongerOperators!type) | |
return true; | |
return true; | |
} | |
default: return false; | |
} | |
} | |
return tryLexLongerOperators!noreturn; | |
} | |
char safePeek() | |
{ | |
return this._index >= this._input.length ? char.init : this._input[this._index]; | |
} | |
char eat() | |
{ | |
return this._input[this._index++]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment