Parser now handles more code. Rearranged token struct to fit in 32 bytes
This commit is contained in:
parent
f7e7cf19ee
commit
95c7c25fc6
|
@ -128,16 +128,17 @@ public:
|
||||||
*/
|
*/
|
||||||
struct Token
|
struct Token
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The token type.
|
|
||||||
*/
|
|
||||||
TokenType type;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The representation of the token in the original source code.
|
* The representation of the token in the original source code.
|
||||||
*/
|
*/
|
||||||
string value;
|
string value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the start of the token in the original source.
|
||||||
|
* $(LPAREN)measured in ASCII characters or UTF-8 code units$(RPAREN)
|
||||||
|
*/
|
||||||
|
size_t startIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of the line the token is on.
|
* The number of the line the token is on.
|
||||||
*/
|
*/
|
||||||
|
@ -147,13 +148,12 @@ struct Token
|
||||||
* The column number of the start of the token in the original source.
|
* The column number of the start of the token in the original source.
|
||||||
* $(LPAREN)measured in ASCII characters or UTF-8 code units$(RPAREN)
|
* $(LPAREN)measured in ASCII characters or UTF-8 code units$(RPAREN)
|
||||||
*/
|
*/
|
||||||
uint column;
|
ushort column;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The index of the start of the token in the original source.
|
* The token type.
|
||||||
* $(LPAREN)measured in ASCII characters or UTF-8 code units$(RPAREN)
|
|
||||||
*/
|
*/
|
||||||
size_t startIndex;
|
TokenType type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if the token is of the same type and has the same string
|
* Check to see if the token is of the same type and has the same string
|
||||||
|
@ -190,7 +190,7 @@ struct Token
|
||||||
* Configure the behavior of the byToken() function. These flags may be
|
* Configure the behavior of the byToken() function. These flags may be
|
||||||
* combined using a bitwise or.
|
* combined using a bitwise or.
|
||||||
*/
|
*/
|
||||||
enum IterationStyle
|
enum IterationStyle : ushort
|
||||||
{
|
{
|
||||||
/// Only include code, not whitespace or comments
|
/// Only include code, not whitespace or comments
|
||||||
codeOnly = 0,
|
codeOnly = 0,
|
||||||
|
@ -210,7 +210,7 @@ enum IterationStyle
|
||||||
* Configuration of the token lexing style. These flags may be combined with a
|
* Configuration of the token lexing style. These flags may be combined with a
|
||||||
* bitwise or.
|
* bitwise or.
|
||||||
*/
|
*/
|
||||||
enum TokenStyle : uint
|
enum TokenStyle : ushort
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Escape sequences will be replaced with their equivalent characters,
|
* Escape sequences will be replaced with their equivalent characters,
|
||||||
|
@ -1836,7 +1836,7 @@ L_advance:
|
||||||
enum initialTableSize = 2048;
|
enum initialTableSize = 2048;
|
||||||
Token current;
|
Token current;
|
||||||
uint lineNumber;
|
uint lineNumber;
|
||||||
uint column;
|
ushort column;
|
||||||
LexSrc src;
|
LexSrc src;
|
||||||
bool _empty;
|
bool _empty;
|
||||||
LexerConfig config;
|
LexerConfig config;
|
||||||
|
|
178
std/d/parser.d
178
std/d/parser.d
|
@ -69,7 +69,7 @@ import std.algorithm;
|
||||||
import std.array;
|
import std.array;
|
||||||
version (unittest) import std.stdio;
|
version (unittest) import std.stdio;
|
||||||
|
|
||||||
//version = development;
|
version = development;
|
||||||
version = verbose;
|
version = verbose;
|
||||||
version(development) import std.stdio;
|
version(development) import std.stdio;
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
|
@ -84,7 +84,10 @@ Module parseModule(const(Token)[] tokens, string fileName)
|
||||||
auto parser = new Parser();
|
auto parser = new Parser();
|
||||||
parser.fileName = fileName;
|
parser.fileName = fileName;
|
||||||
parser.tokens = tokens;
|
parser.tokens = tokens;
|
||||||
return parser.parseModule();
|
auto mod = parser.parseModule();
|
||||||
|
version (development) writeln("Parsing finished with ", parser.errorCount,
|
||||||
|
" errors");
|
||||||
|
return mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,7 +105,7 @@ struct Parser
|
||||||
*/
|
*/
|
||||||
AddExpression parseAddExpression()
|
AddExpression parseAddExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseAddExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
return parseLeftAssocBinaryExpression!(AddExpression, MulExpression,
|
return parseLeftAssocBinaryExpression!(AddExpression, MulExpression,
|
||||||
TokenType.plus, TokenType.minus, TokenType.tilde)();
|
TokenType.plus, TokenType.minus, TokenType.tilde)();
|
||||||
}
|
}
|
||||||
|
@ -135,9 +138,7 @@ struct Parser
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((node.type = parseType()) is null) return null;
|
if ((node.type = parseType()) is null) return null;
|
||||||
writeln("type parsed");
|
|
||||||
if ((node.declarator = parseDeclarator()) is null) return null;
|
if ((node.declarator = parseDeclarator()) is null) return null;
|
||||||
writeln("declarator parsed");
|
|
||||||
}
|
}
|
||||||
if (expect(TokenType.semicolon) is null) return null;
|
if (expect(TokenType.semicolon) is null) return null;
|
||||||
return node;
|
return node;
|
||||||
|
@ -223,7 +224,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
||||||
*/
|
*/
|
||||||
AndAndExpression parseAndAndExpression()
|
AndAndExpression parseAndAndExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseAndAndExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
return parseLeftAssocBinaryExpression!(AndAndExpression, OrExpression,
|
return parseLeftAssocBinaryExpression!(AndAndExpression, OrExpression,
|
||||||
TokenType.logicAnd)();
|
TokenType.logicAnd)();
|
||||||
}
|
}
|
||||||
|
@ -238,7 +239,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
||||||
*/
|
*/
|
||||||
AndExpression parseAndExpression()
|
AndExpression parseAndExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseAndExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
return parseLeftAssocBinaryExpression!(AndExpression, CmpExpression,
|
return parseLeftAssocBinaryExpression!(AndExpression, CmpExpression,
|
||||||
TokenType.bitAnd)();
|
TokenType.bitAnd)();
|
||||||
}
|
}
|
||||||
|
@ -252,8 +253,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
||||||
*/
|
*/
|
||||||
ArgumentList parseArgumentList()
|
ArgumentList parseArgumentList()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseArgumentList ", current.line, " ", current.column);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
version(verbose) scope(exit) writeln("<parseArgumentList ", current.line, " ", current.column);
|
|
||||||
return parseCommaSeparatedRule!(ArgumentList, AssignExpression)();
|
return parseCommaSeparatedRule!(ArgumentList, AssignExpression)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,8 +267,9 @@ alias core.sys.posix.stdio.fileno fileno;
|
||||||
Arguments parseArguments()
|
Arguments parseArguments()
|
||||||
{
|
{
|
||||||
auto node = new Arguments;
|
auto node = new Arguments;
|
||||||
version (verbose) writeln(">parseArguments");
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
if (expect(TokenType.lParen) is null) return null;
|
if (expect(TokenType.lParen) is null) return null;
|
||||||
|
if (!currentIs(TokenType.rParen))
|
||||||
node.argumentList = parseArgumentList();
|
node.argumentList = parseArgumentList();
|
||||||
if (expect(TokenType.rParen) is null) return null;
|
if (expect(TokenType.rParen) is null) return null;
|
||||||
return node;
|
return node;
|
||||||
|
@ -663,7 +664,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
||||||
*/
|
*/
|
||||||
AssignExpression parseAssignExpression()
|
AssignExpression parseAssignExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseAssignExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new AssignExpression;
|
auto node = new AssignExpression;
|
||||||
node.ternaryExpression = parseTernaryExpression();
|
node.ternaryExpression = parseTernaryExpression();
|
||||||
if (currentIsOneOf(TokenType.assign, TokenType.unsignedShiftRightEqual,
|
if (currentIsOneOf(TokenType.assign, TokenType.unsignedShiftRightEqual,
|
||||||
|
@ -844,8 +845,8 @@ alias core.sys.posix.stdio.fileno fileno;
|
||||||
*/
|
*/
|
||||||
AutoDeclaration parseAutoDeclaration()
|
AutoDeclaration parseAutoDeclaration()
|
||||||
{
|
{
|
||||||
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new AutoDeclaration;
|
auto node = new AutoDeclaration;
|
||||||
version(verbose) writeln(">parseAutoDeclaration ", current.line);
|
|
||||||
node.storageClass = parseStorageClass();
|
node.storageClass = parseStorageClass();
|
||||||
if (node.storageClass is null) return null;
|
if (node.storageClass is null) return null;
|
||||||
do
|
do
|
||||||
|
@ -862,6 +863,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
} while (true);
|
} while (true);
|
||||||
|
if (expect(TokenType.semicolon) is null) return null;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,7 +1350,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
||||||
*/
|
*/
|
||||||
CmpExpression parseCmpExpression()
|
CmpExpression parseCmpExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseCmpExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new CmpExpression;
|
auto node = new CmpExpression;
|
||||||
auto shift = parseShiftExpression();
|
auto shift = parseShiftExpression();
|
||||||
with (TokenType) switch (current.type)
|
with (TokenType) switch (current.type)
|
||||||
|
@ -1643,7 +1645,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
||||||
*/
|
*/
|
||||||
Declaration parseDeclaration()
|
Declaration parseDeclaration()
|
||||||
{
|
{
|
||||||
import std.stdio;
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new Declaration;
|
auto node = new Declaration;
|
||||||
with (TokenType) switch (current.type)
|
with (TokenType) switch (current.type)
|
||||||
{
|
{
|
||||||
|
@ -1698,6 +1700,8 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
||||||
node.sharedStaticConstructor = parseSharedStaticConstructor();
|
node.sharedStaticConstructor = parseSharedStaticConstructor();
|
||||||
else if (startsWith(shared_, static_, tilde))
|
else if (startsWith(shared_, static_, tilde))
|
||||||
node.sharedStaticDestructor = parseSharedStaticDestructor();
|
node.sharedStaticDestructor = parseSharedStaticDestructor();
|
||||||
|
else if (peekIs(lParen))
|
||||||
|
goto type;
|
||||||
else
|
else
|
||||||
node.attributedDeclaration = parseAttributedDeclaration();
|
node.attributedDeclaration = parseAttributedDeclaration();
|
||||||
break;
|
break;
|
||||||
|
@ -1725,6 +1729,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
||||||
break;
|
break;
|
||||||
case bool_: .. case wchar_:
|
case bool_: .. case wchar_:
|
||||||
case identifier:
|
case identifier:
|
||||||
|
type:
|
||||||
Type type = parseType();
|
Type type = parseType();
|
||||||
if (!currentIs(identifier))
|
if (!currentIs(identifier))
|
||||||
{
|
{
|
||||||
|
@ -1769,6 +1774,13 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case const_:
|
||||||
|
case immutable_:
|
||||||
|
case inout_:
|
||||||
|
if (peekIs(TokenType.lParen))
|
||||||
|
goto type;
|
||||||
|
else
|
||||||
|
goto case;
|
||||||
case at:
|
case at:
|
||||||
case align_:
|
case align_:
|
||||||
case deprecated_:
|
case deprecated_:
|
||||||
|
@ -1782,10 +1794,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
||||||
case synchronized_:
|
case synchronized_:
|
||||||
case override_:
|
case override_:
|
||||||
case abstract_:
|
case abstract_:
|
||||||
case const_:
|
|
||||||
case gshared:
|
case gshared:
|
||||||
case immutable_:
|
|
||||||
case inout_:
|
|
||||||
case pure_:
|
case pure_:
|
||||||
case nothrow_:
|
case nothrow_:
|
||||||
node.attributedDeclaration = parseAttributedDeclaration();
|
node.attributedDeclaration = parseAttributedDeclaration();
|
||||||
|
@ -2086,7 +2095,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
||||||
*/
|
*/
|
||||||
EqualExpression parseEqualExpression(ShiftExpression shift = null)
|
EqualExpression parseEqualExpression(ShiftExpression shift = null)
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseEqualExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new EqualExpression;
|
auto node = new EqualExpression;
|
||||||
node.left = shift is null ? parseShiftExpression() : shift;
|
node.left = shift is null ? parseShiftExpression() : shift;
|
||||||
if (currentIsOneOf(TokenType.equal, TokenType.notEqual))
|
if (currentIsOneOf(TokenType.equal, TokenType.notEqual))
|
||||||
|
@ -2380,8 +2389,8 @@ body {} // six
|
||||||
*/
|
*/
|
||||||
FunctionCallExpression parseFunctionCallExpression(UnaryExpression unary = null)
|
FunctionCallExpression parseFunctionCallExpression(UnaryExpression unary = null)
|
||||||
{
|
{
|
||||||
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new FunctionCallExpression;
|
auto node = new FunctionCallExpression;
|
||||||
version (verbose) writeln(">parseFunctionCallExpression ", current.line);
|
|
||||||
node.unaryExpression = unary is null ? parseUnaryExpression() : unary;
|
node.unaryExpression = unary is null ? parseUnaryExpression() : unary;
|
||||||
if (currentIs(TokenType.not))
|
if (currentIs(TokenType.not))
|
||||||
node.templateArguments = parseTemplateArguments();
|
node.templateArguments = parseTemplateArguments();
|
||||||
|
@ -2628,9 +2637,13 @@ body {} // six
|
||||||
*/
|
*/
|
||||||
IdentifierOrTemplateInstance parseIdentifierOrTemplateInstance()
|
IdentifierOrTemplateInstance parseIdentifierOrTemplateInstance()
|
||||||
{
|
{
|
||||||
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new IdentifierOrTemplateInstance;
|
auto node = new IdentifierOrTemplateInstance;
|
||||||
if (peekIs(TokenType.not))
|
if (peekIs(TokenType.not) && !startsWith(TokenType.identifier,
|
||||||
|
TokenType.not, TokenType.is_))
|
||||||
|
{
|
||||||
node.templateInstance = parseTemplateInstance();
|
node.templateInstance = parseTemplateInstance();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto ident = expect(TokenType.identifier);
|
auto ident = expect(TokenType.identifier);
|
||||||
|
@ -2649,7 +2662,7 @@ body {} // six
|
||||||
*/
|
*/
|
||||||
IdentityExpression parseIdentityExpression(ShiftExpression shift = null)
|
IdentityExpression parseIdentityExpression(ShiftExpression shift = null)
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseIdentityExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new IdentityExpression;
|
auto node = new IdentityExpression;
|
||||||
node.left = shift is null ? parseShiftExpression() : shift;
|
node.left = shift is null ? parseShiftExpression() : shift;
|
||||||
if (currentIs(TokenType.not))
|
if (currentIs(TokenType.not))
|
||||||
|
@ -2671,6 +2684,7 @@ body {} // six
|
||||||
*/
|
*/
|
||||||
IfStatement parseIfStatement()
|
IfStatement parseIfStatement()
|
||||||
{
|
{
|
||||||
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new IfStatement;
|
auto node = new IfStatement;
|
||||||
if (expect(TokenType.if_) is null) return null;
|
if (expect(TokenType.if_) is null) return null;
|
||||||
if (expect(TokenType.lParen) is null) return null;
|
if (expect(TokenType.lParen) is null) return null;
|
||||||
|
@ -2855,8 +2869,8 @@ import core.stdc.stdio, std.string : KeepTerminator;
|
||||||
*/
|
*/
|
||||||
IndexExpression parseIndexExpression(UnaryExpression unaryExpression = null)
|
IndexExpression parseIndexExpression(UnaryExpression unaryExpression = null)
|
||||||
{
|
{
|
||||||
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new IndexExpression;
|
auto node = new IndexExpression;
|
||||||
version (verbose) writeln(">parseIndexExpression ", current.line);
|
|
||||||
node.unaryExpression = unaryExpression is null ? parseUnaryExpression() : unaryExpression;
|
node.unaryExpression = unaryExpression is null ? parseUnaryExpression() : unaryExpression;
|
||||||
if (expect(TokenType.lBracket) is null) return null;
|
if (expect(TokenType.lBracket) is null) return null;
|
||||||
node.argumentList = parseArgumentList();
|
node.argumentList = parseArgumentList();
|
||||||
|
@ -3357,7 +3371,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
MulExpression parseMulExpression()
|
MulExpression parseMulExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseMulExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
return parseLeftAssocBinaryExpression!(MulExpression, UnaryExpression,
|
return parseLeftAssocBinaryExpression!(MulExpression, UnaryExpression,
|
||||||
TokenType.star, TokenType.div, TokenType.mod)();
|
TokenType.star, TokenType.div, TokenType.mod)();
|
||||||
}
|
}
|
||||||
|
@ -3582,7 +3596,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
OrExpression parseOrExpression()
|
OrExpression parseOrExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseOrExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
return parseLeftAssocBinaryExpression!(OrExpression, XorExpression,
|
return parseLeftAssocBinaryExpression!(OrExpression, XorExpression,
|
||||||
TokenType.bitOr)();
|
TokenType.bitOr)();
|
||||||
}
|
}
|
||||||
|
@ -3597,7 +3611,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
OrOrExpression parseOrOrExpression()
|
OrOrExpression parseOrOrExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseOrOrExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
return parseLeftAssocBinaryExpression!(OrOrExpression, AndAndExpression,
|
return parseLeftAssocBinaryExpression!(OrOrExpression, AndAndExpression,
|
||||||
TokenType.logicOr)();
|
TokenType.logicOr)();
|
||||||
}
|
}
|
||||||
|
@ -3634,8 +3648,8 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
Parameter parseParameter()
|
Parameter parseParameter()
|
||||||
{
|
{
|
||||||
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new Parameter;
|
auto node = new Parameter;
|
||||||
version (verbose) writeln(">parseParameter");
|
|
||||||
while (moreTokens())
|
while (moreTokens())
|
||||||
{
|
{
|
||||||
TokenType type = parseParameterAttribute(false);
|
TokenType type = parseParameterAttribute(false);
|
||||||
|
@ -3650,7 +3664,10 @@ invariant() foo();
|
||||||
{
|
{
|
||||||
node.name = advance();
|
node.name = advance();
|
||||||
if (currentIs(TokenType.vararg))
|
if (currentIs(TokenType.vararg))
|
||||||
|
{
|
||||||
|
advance();
|
||||||
node.vararg = true;
|
node.vararg = true;
|
||||||
|
}
|
||||||
else if (currentIs(TokenType.assign))
|
else if (currentIs(TokenType.assign))
|
||||||
{
|
{
|
||||||
advance();
|
advance();
|
||||||
|
@ -3716,7 +3733,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
Parameters parseParameters()
|
Parameters parseParameters()
|
||||||
{
|
{
|
||||||
version (verbose) writeln(">parseParameters");
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new Parameters;
|
auto node = new Parameters;
|
||||||
expect(TokenType.lParen);
|
expect(TokenType.lParen);
|
||||||
if (currentIs(TokenType.rParen))
|
if (currentIs(TokenType.rParen))
|
||||||
|
@ -3926,8 +3943,7 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
PrimaryExpression parsePrimaryExpression()
|
PrimaryExpression parsePrimaryExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parsePrimaryExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
version(verbose) scope(exit) writeln("finished parsePrimaryExpression ", current.line, " ", current.column);
|
|
||||||
auto node = new PrimaryExpression;
|
auto node = new PrimaryExpression;
|
||||||
with (TokenType) switch (current.type)
|
with (TokenType) switch (current.type)
|
||||||
{
|
{
|
||||||
|
@ -4149,7 +4165,7 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
ShiftExpression parseShiftExpression()
|
ShiftExpression parseShiftExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseShiftExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
return parseLeftAssocBinaryExpression!(ShiftExpression, AddExpression,
|
return parseLeftAssocBinaryExpression!(ShiftExpression, AddExpression,
|
||||||
TokenType.shiftLeft, TokenType.shiftRight,
|
TokenType.shiftLeft, TokenType.shiftRight,
|
||||||
TokenType.unsignedShiftRight)();
|
TokenType.unsignedShiftRight)();
|
||||||
|
@ -4685,7 +4701,7 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
TemplateDeclaration parseTemplateDeclaration()
|
TemplateDeclaration parseTemplateDeclaration()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseTemplateDeclaration");
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new TemplateDeclaration;
|
auto node = new TemplateDeclaration;
|
||||||
expect(TokenType.template_);
|
expect(TokenType.template_);
|
||||||
auto ident = expect(TokenType.identifier);
|
auto ident = expect(TokenType.identifier);
|
||||||
|
@ -4754,7 +4770,7 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
TemplateParameter parseTemplateParameter()
|
TemplateParameter parseTemplateParameter()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseTemplateParameter");
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new TemplateParameter;
|
auto node = new TemplateParameter;
|
||||||
with (TokenType) switch (current.type)
|
with (TokenType) switch (current.type)
|
||||||
{
|
{
|
||||||
|
@ -4800,7 +4816,7 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
TemplateParameters parseTemplateParameters()
|
TemplateParameters parseTemplateParameters()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseTemplateParameters");
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new TemplateParameters;
|
auto node = new TemplateParameters;
|
||||||
assert (expect(TokenType.lParen));
|
assert (expect(TokenType.lParen));
|
||||||
node.templateParameterList = parseTemplateParameterList();
|
node.templateParameterList = parseTemplateParameterList();
|
||||||
|
@ -4880,7 +4896,7 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
TemplateTupleParameter parseTemplateTupleParameter()
|
TemplateTupleParameter parseTemplateTupleParameter()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseTemplateTupleParameter");
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new TemplateTupleParameter;
|
auto node = new TemplateTupleParameter;
|
||||||
auto i = expect(TokenType.identifier);
|
auto i = expect(TokenType.identifier);
|
||||||
if (i is null)
|
if (i is null)
|
||||||
|
@ -4979,7 +4995,7 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
TernaryExpression parseTernaryExpression()
|
TernaryExpression parseTernaryExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseTernaryExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new TernaryExpression;
|
auto node = new TernaryExpression;
|
||||||
node.orOrExpression = parseOrOrExpression();
|
node.orOrExpression = parseOrOrExpression();
|
||||||
if (currentIs(TokenType.ternary))
|
if (currentIs(TokenType.ternary))
|
||||||
|
@ -5056,6 +5072,7 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
Type parseType()
|
Type parseType()
|
||||||
{
|
{
|
||||||
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new Type;
|
auto node = new Type;
|
||||||
switch(current.type)
|
switch(current.type)
|
||||||
{
|
{
|
||||||
|
@ -5247,8 +5264,8 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
TypeSuffix parseTypeSuffix()
|
TypeSuffix parseTypeSuffix()
|
||||||
{
|
{
|
||||||
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new TypeSuffix;
|
auto node = new TypeSuffix;
|
||||||
version (verbose) writeln(">parseTypeSuffix");
|
|
||||||
with (TokenType) switch(current.type)
|
with (TokenType) switch(current.type)
|
||||||
{
|
{
|
||||||
case star:
|
case star:
|
||||||
|
@ -5358,8 +5375,7 @@ q{(int a, ...)
|
||||||
*/
|
*/
|
||||||
UnaryExpression parseUnaryExpression()
|
UnaryExpression parseUnaryExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseUnaryExpression ", current.line, " ", current.column);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
version(verbose) scope(exit) writeln("<parseUnaryExpression ", current.line, " ", current.column);
|
|
||||||
auto node = new UnaryExpression;
|
auto node = new UnaryExpression;
|
||||||
with(TokenType) switch (current.type)
|
with(TokenType) switch (current.type)
|
||||||
{
|
{
|
||||||
|
@ -5393,6 +5409,8 @@ q{(int a, ...)
|
||||||
loop: while (moreTokens()) with (TokenType) switch (current.type)
|
loop: while (moreTokens()) with (TokenType) switch (current.type)
|
||||||
{
|
{
|
||||||
case not:
|
case not:
|
||||||
|
if (peekIs(is_))
|
||||||
|
break loop;
|
||||||
index++;
|
index++;
|
||||||
bool jump = (currentIs(TokenType.lParen) && peekPastParens().type == TokenType.lParen)
|
bool jump = (currentIs(TokenType.lParen) && peekPastParens().type == TokenType.lParen)
|
||||||
|| peekIs(TokenType.lParen);
|
|| peekIs(TokenType.lParen);
|
||||||
|
@ -5501,14 +5519,16 @@ q{doStuff(5)}c;
|
||||||
*/
|
*/
|
||||||
VariableDeclaration parseVariableDeclaration(Type type = null)
|
VariableDeclaration parseVariableDeclaration(Type type = null)
|
||||||
{
|
{
|
||||||
|
mixin (traceEnterAndExit!(__FUNCTION__));
|
||||||
auto node = new VariableDeclaration;
|
auto node = new VariableDeclaration;
|
||||||
|
|
||||||
if (currentIs(TokenType.auto_))
|
if (currentIs(TokenType.auto_))
|
||||||
{
|
{
|
||||||
node.autoDeclaration = parseAutoDeclaration();
|
node.autoDeclaration = parseAutoDeclaration();
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: handle storage class here
|
||||||
|
|
||||||
node.type = type is null ? parseType() : type;
|
node.type = type is null ? parseType() : type;
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
|
@ -5637,7 +5657,7 @@ q{doStuff(5)}c;
|
||||||
*/
|
*/
|
||||||
XorExpression parseXorExpression()
|
XorExpression parseXorExpression()
|
||||||
{
|
{
|
||||||
version(verbose) writeln(">parseXorExpression ", current.line);
|
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||||
return parseLeftAssocBinaryExpression!(XorExpression, AndExpression,
|
return parseLeftAssocBinaryExpression!(XorExpression, AndExpression,
|
||||||
TokenType.xor)();
|
TokenType.xor)();
|
||||||
}
|
}
|
||||||
|
@ -5675,6 +5695,60 @@ private:
|
||||||
|
|
||||||
bool isDeclaration()
|
bool isDeclaration()
|
||||||
{
|
{
|
||||||
|
with (TokenType) switch (current.type)
|
||||||
|
{
|
||||||
|
mixin(BASIC_TYPE_CASE_RANGE);
|
||||||
|
case const_:
|
||||||
|
case immutable_:
|
||||||
|
case inout_:
|
||||||
|
case shared_:
|
||||||
|
case gshared:
|
||||||
|
case alias_:
|
||||||
|
case class_:
|
||||||
|
case enum_:
|
||||||
|
case interface_:
|
||||||
|
case struct_:
|
||||||
|
case union_:
|
||||||
|
case unittest_:
|
||||||
|
case auto_:
|
||||||
|
case ref_:
|
||||||
|
case at:
|
||||||
|
case align_:
|
||||||
|
case deprecated_:
|
||||||
|
case private_:
|
||||||
|
case package_:
|
||||||
|
case protected_:
|
||||||
|
case public_:
|
||||||
|
case export_:
|
||||||
|
case extern_:
|
||||||
|
case final_:
|
||||||
|
case synchronized_:
|
||||||
|
case override_:
|
||||||
|
case abstract_:
|
||||||
|
case pure_:
|
||||||
|
case nothrow_:
|
||||||
|
return true;
|
||||||
|
case case_:
|
||||||
|
case default_:
|
||||||
|
case return_:
|
||||||
|
case if_:
|
||||||
|
case while_:
|
||||||
|
case do_:
|
||||||
|
case for_:
|
||||||
|
case foreach_:
|
||||||
|
case switch_:
|
||||||
|
case continue_:
|
||||||
|
case break_:
|
||||||
|
case goto_:
|
||||||
|
case try_:
|
||||||
|
case throw_:
|
||||||
|
case scope_:
|
||||||
|
case asm_:
|
||||||
|
case foreach_reverse_:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
// h4x
|
// h4x
|
||||||
auto b = setBookmark();
|
auto b = setBookmark();
|
||||||
scope(exit) goToBookmark(b);
|
scope(exit) goToBookmark(b);
|
||||||
|
@ -5755,11 +5829,11 @@ private:
|
||||||
void error(lazy string message)
|
void error(lazy string message)
|
||||||
{
|
{
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
++errorCount;
|
|
||||||
if (suppressMessages <= 0)
|
if (suppressMessages <= 0)
|
||||||
{
|
{
|
||||||
|
++errorCount;
|
||||||
if (errorFunction is null)
|
if (errorFunction is null)
|
||||||
stderr.writefln("%s(%d:%d): %s", fileName, tokens[index].line,
|
stderr.writefln("!! %s(%d:%d): %s", fileName, tokens[index].line,
|
||||||
tokens[index].column, message);
|
tokens[index].column, message);
|
||||||
else
|
else
|
||||||
errorFunction(fileName, tokens[index].line, tokens[index].column,
|
errorFunction(fileName, tokens[index].line, tokens[index].column,
|
||||||
|
@ -5875,16 +5949,16 @@ private:
|
||||||
*/
|
*/
|
||||||
const(Token)* expect(TokenType type, string loc = __PRETTY_FUNCTION__)
|
const(Token)* expect(TokenType type, string loc = __PRETTY_FUNCTION__)
|
||||||
{
|
{
|
||||||
if (tokens[index].type == type)
|
if (index < tokens.length && tokens[index].type == type)
|
||||||
return &tokens[index++];
|
return &tokens[index++];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (tokenValues[type] is null)
|
if (tokenValues[type] is null)
|
||||||
error("Expected " ~ to!string(type) ~ " instead of "
|
error("Expected " ~ to!string(type) ~ " instead of "
|
||||||
~ tokens[index].value ~ " at " ~ loc);
|
~ (index < tokens.length ? tokens[index].value : "EOF") ~ " at " ~ loc);
|
||||||
else
|
else
|
||||||
error("Expected " ~ tokenValues[type] ~ " instead of "
|
error("Expected " ~ tokenValues[type] ~ " instead of "
|
||||||
~ tokens[index].value ~ " at " ~ loc);
|
~ (index < tokens.length ? tokens[index].value : "EOF") ~ " at " ~ loc);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5966,6 +6040,20 @@ private:
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template traceEnterAndExit(string fun)
|
||||||
|
{
|
||||||
|
enum traceEnterAndExit = `version (verbose) trace(">> ` ~ fun ~ ` ");`
|
||||||
|
~ `version (verbose) scope(exit) trace("<< ` ~ fun ~ ` ");`;
|
||||||
|
}
|
||||||
|
|
||||||
|
version (verbose) void trace(string message)
|
||||||
|
{
|
||||||
|
if (index < tokens.length)
|
||||||
|
stderr.writeln(message, "(", current.line, ":", current.column, ")");
|
||||||
|
else
|
||||||
|
stderr.writeln(message, "(EOF:0)");
|
||||||
|
}
|
||||||
|
|
||||||
uint errorCount;
|
uint errorCount;
|
||||||
const(Token)[] tokens;
|
const(Token)[] tokens;
|
||||||
size_t index;
|
size_t index;
|
||||||
|
|
Loading…
Reference in New Issue