Skip to content

Instantly share code, notes, and snippets.

@BradleyChatha
Created February 7, 2023 15:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BradleyChatha/873077996b36c9f575fa2410e03705d5 to your computer and use it in GitHub Desktop.
Save BradleyChatha/873077996b36c9f575fa2410e03705d5 to your computer and use it in GitHub Desktop.
D Bugzilla Report Code
// 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