D-Scanner/std/d/parser.d

4002 lines
107 KiB
D
Executable File

// Written in the D programming language
/**
* This module contains a _parser for D source code.
*
* Examples:
* ---
* // TODO
* ---
*
* Copyright: Brian Schott 2013
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt Boost, License 1.0)
* Authors: Brian Schott
* Source: $(PHOBOSSRC std/d/_parser.d)
* MACROS:
* GRAMMAR = <pre style="font-weight: bold">$0</pre>
* RULEDEF = <a name="$0"><span>$0</span></a>
* RULE = <a href="#$0"><span style="font-weight: bold">$0</span></a>
* LITERAL = <span style="color: green; font-weight: normal;">$0</span>
*/
module std.d.parser;
import std.d.lexer;
import std.d.ast;
import std.conv;
import std.algorithm;
import std.array;
version(unittest) import std.stdio;
/**
* Params:
* tokens = the tokens parsed by std.d.lexer
* Returns: the parsed module
*/
Module parseModule(R)(R tokens) if (is (ElementType!R == Token))
{
auto parser = new Parser();
parser.tokens = tokens.array();
return parser.parseModule();
}
/**
* Parser structure
*/
struct Parser
{
/**
* Parses an AddExpression.
*
* $(GRAMMAR $(RULEDEF addExpression):
* $(RULE mulExpression)
* | $(RULE addExpression) $(LPAREN)$(LITERAL '+') | $(LITERAL'-') | $(LITERAL'~')$(RPAREN) $(RULE mulExpression)
* ;)
*/
AddExpression parseAddExpression()
{
auto node = new AddExpression;
node.right = parseMulExpression();
while (currentIsOneOf(TokenType.plus, TokenType.minus, TokenType.tilde))
{
node.operator = advance().type;
auto newNode = new AddExpression;
newNode.left = node;
newNode.right = parseMulExpression();
node = newNode;
}
return node;
}
/**
* Parses an AliasDeclaration.
*
* $(GRAMMAR $(RULEDEF aliasDeclaration):
* $(LITERAL 'alias') $(LPAREN)$(RULE aliasInitializer) $(LPAREN)$(LITERAL ',') $(RULE aliasInitializer)$(RPAREN)* | $(RULE type) $(RULE declarator)$(RPAREN) $(LITERAL ';')
* ;)
*/
AliasDeclaration parseAliasDeclaration()
{
auto node = new AliasDeclaration;
expect(TokenType.alias_);
// TODO
expect(TokenType.semicolon);
return node;
}
/**
* Parses an AliasInitializer
* $(GRAMMAR $(RULEDEF aliasInitializer):
* $(LITERAL Identifier) $(LITERAL '=') $(RULE type)
* ;)
*/
AliasInitializer parseAliasInitializer()
{
auto node = new AliasInitializer;
node.identifier = *expect(TokenType.identifier);
expect(TokenType.assign);
node.type = parseType();
return node;
}
/**
* Parses an AliasThisDeclaration
* $(GRAMMAR $(RULEDEF aliasThisDeclaration): $(LITERAL 'alias') $(LITERAL Identifier) $(LITERAL 'this') $(LITERAL ';')
* ;)
*/
AliasThisDeclaration parseAliasThisDeclaration()
{
auto node = new AliasThisDeclaration;
expect(TokenType.alias_);
node.identifier = *expect(TokenType.identifier);
expect(TokenType.this_);
expect(TokenType.semicolon);
return node;
}
/**
* Parses an AlignAttribute.
* $(GRAMMAR $(RULEDEF alignAttribute): $(LITERAL 'align') ($(LITERAL '$(LPAREN)') $(LITERAL IntegerLiteral) $(LITERAL '$(RPAREN)'))?
* ;)
*/
AlignAttribute parseAlignAttribute()
{
auto node = new AlignAttribute;
expect(TokenType.align_);
if (currentIs(TokenType.lParen))
{
expect(TokenType.lParen);
node.intLiteral = *expect(TokenType.intLiteral);
expect(TokenType.rParen);
}
return node;
}
/**
* Parses an AndAndExpression
* $(GRAMMAR $(RULEDEF andAndExpression):
* $(RULE orExpression)
* | $(RULE andAndExpression) $(LITERAL '&&') $(RULE orExpression)
* ;)
*/
AndAndExpression parseAndAndExpression()
{
auto node = new AndAndExpression;
node.right = parseOrExpression();
while (currentIs(TokenType.logicAnd))
{
advance();
auto node2 = new AndAndExpression;
node2.left = node;
node2.right = parseOrExpression();
node = node2;
}
return node;
}
/**
* Parses an AndExpression
*
* $(GRAMMAR $(RULEDEF andExpression):
* $(RULE cmpExpression)
* | $(RULE andExpression) $(LITERAL '&') $(RULE cmpExpression)
* ;)
*/
AndExpression parseAndExpression()
{
auto node = new AndExpression;
// TODO
return node;
}
/**
* Parses an ArgumentList
*
* $(GRAMMAR $(RULEDEF argumentList):
* $(RULE assignExpression) ($(LITERAL ',') $(RULE assignExpression)?)*
* ;)
*/
ArgumentList parseArgumentList()
{
auto node = new ArgumentList;
while (true)
{
node.arguments ~= parseAssignExpression();
if (moreTokens() && currentIs(TokenType.comma))
{
advance();
continue;
}
else
break;
}
return node;
}
/**
* Parses Arguments
*
* $(GRAMMAR $(RULEDEF arguments):
* $(LITERAL '$(LPAREN)') $(RULE argumentList)? $(LITERAL '$(RPAREN)')
* ;)
*/
Arguments parseArguments()
{
auto node = new Arguments;
expect(TokenType.lParen);
node.argumentList = parseArgumentList();
expect(TokenType.rParen);
return node;
}
/**
* Parses an ArrayInitializer
*
* $(GRAMMAR $(RULEDEF arrayInitializer):
* $(LITERAL '[') $(LITERAL ']')
* | $(LITERAL '[') $(RULE arrayMemberInitialization) ($(LITERAL ',') $(RULE arrayMemberInitialization))* $(LITERAL ']')
* ;)
*/
ArrayInitializer parseArrayInitializer()
{
auto node = new ArrayInitializer;
expect(TokenType.lBracket);
while (true)
{
node.arrayMemberInitializations ~= parseArrayMemberInitialization();
if (currentIs(TokenType.comma))
{
advance();
continue;
}
else
break;
}
expect(TokenType.rBracket);
return node;
}
/**
* Parses an ArrayLiteral
*
* $(GRAMMAR $(RULEDEF arrayLiteral):
* $(LITERAL '[') $(RULE argumentList) $(LITERAL ']')
* ;)
*/
ArrayLiteral parseArrayLiteral()
{
auto node = new ArrayLiteral;
expect(TokenType.lBracket);
node.argumentList = parseArgumentList();
expect(TokenType.rBracket);
return node;
}
/**
* Parses an ArrayMemberInitialization
*
* $(GRAMMAR $(RULEDEF arrayMemberInitialization):
* ($(RULE assignExpression) $(LITERAL ':'))? $(RULE nonVoidInitializer)
* ;)
*/
ArrayMemberInitialization parseArrayMemberInitialization()
{
auto node = new ArrayMemberInitialization;
// TODO
return node;
}
/**
* Parses an AsmAddExp
*
* $(GRAMMAR $(RULEDEF asmAddExp):
* $(RULE asmMulExp) (($(LITERAL '+') | $(LITERAL '-')) $(RULE asmMulExp))?
* ;)
*/
AsmAddExp parseAsmAddExp()
{
auto node = new AsmAddExp;
// TODO
return node;
}
/**
* Parses an AsmAndExp
*
* $(GRAMMAR $(RULEDEF asmAndExp):
* $(RULE asmEqualExp) ($(LITERAL '&') $(RULE asmEqualExp))?
* ;)
*/
AsmAndExp parseAsmAndExp()
{
auto node = new AsmAndExp;
// TODO
return node;
}
/**
* Parses an AsmBrExp
*
* $(GRAMMAR $(RULEDEF asmBrExp):
* $(RULE asmUnaExp)
* | $(RULE asmBrExp) $(LITERAL '[') $(RULE asmExp) $(LITERAL ']')
* ;)
*/
AsmBrExp parseAsmBrExp()
{
auto node = new AsmBrExp;
// TODO
return node;
}
/**
* Parses an AsmEqualExp
*
* $(GRAMMAR $(RULEDEF asmEqualExp):
* $(RULE asmRelExp) (('==' | '!=') $(RULE asmRelExp))?
* ;)
*/
AsmEqualExp parseAsmEqualExp()
{
auto node = new AsmEqualExp;
// TODO
return node;
}
/**
* Parses an AsmExp
*
* $(GRAMMAR $(RULEDEF asmExp):
* $(RULE asmLogOrExp) ($(LITERAL '?') $(RULE asmExp) $(LITERAL ':') $(RULE asmExp))?
* ;)
*/
AsmExp parseAsmExp()
{
auto node = new AsmExp;
// TODO
return node;
}
/**
* Parses an AsmInstruction
*
* $(GRAMMAR $(RULEDEF asmInstruction):
* $(LITERAL Identifier)
* | $(LITERAL 'align') I$(RULE ntegerLiteral)
* | $(LITERAL 'align') $(LITERAL Identifier)
* | $(LITERAL Identifier) $(LITERAL ':') $(RULE asmInstruction)
* | $(LITERAL Identifier) $(RULE asmExp)
* | $(RULE opcode) $(RULE operands)
* ;)
*/
AsmInstruction parseAsmInstruction()
{
auto node = new AsmInstruction;
// TODO
return node;
}
/**
* Parses an AsmLogAndExp
*
* $(GRAMMAR $(RULEDEF asmLogAndExp):
* $(RULE asmOrExp) ('&&' $(RULE asmOrExp))?
* ;)
*/
AsmLogAndExp parseAsmLogAndExp()
{
auto node = new AsmLogAndExp;
// TODO
return node;
}
/**
* Parses an AsmLogOrExp
*
* $(GRAMMAR $(RULEDEF asmLogOrExp):
* $(RULE asmLogAndExp) ('||' $(RULE asmLogAndExp))?
* ;)
*/
AsmLogOrExp parseAsmLogOrExp()
{
auto node = new AsmLogOrExp;
// TODO
return node;
}
/**
* Parses an AsmMulExp
*
* $(GRAMMAR $(RULEDEF asmMulExp):
* $(RULE asmBrExp) (($(LITERAL '*') | $(LITERAL '/') | $(LITERAL '%')) $(RULE asmBrExp))?
* ;)
*/
AsmMulExp parseAsmMulExp()
{
auto node = new AsmMulExp;
// TODO
return node;
}
/**
* Parses an AsmOrExp
*
* $(GRAMMAR $(RULEDEF asmOrExp):
* $(RULE asmXorExp) ($(LITERAL '|') $(RULE asmXorExp))?
* ;)
*/
AsmOrExp parseAsmOrExp()
{
auto node = new AsmOrExp;
// TODO
return node;
}
/**
* Parses an AsmPrimaryExp
*
* $(GRAMMAR $(RULEDEF asmPrimaryExp):
* $(RULE IntegerLiteral)
* | $(RULE FloatLiteral)
* | $(RULE register)
* | $(RULE identifierChain)
* | $(LITERAL '$')
* ;)
*/
AsmPrimaryExp parseAsmPrimaryExp()
{
auto node = new AsmPrimaryExp;
// TODO
return node;
}
/**
* Parses an AsmRelExp
*
* $(GRAMMAR $(RULEDEF asmRelExp):
* $(RULE asmShiftExp) (($(LITERAL '<') | $(LITERAL '<=') | $(LITERAL '>') | $(LITERAL '>=')) $(RULE asmShiftExp))?
* ;)
*/
AsmRelExp parseAsmRelExp()
{
auto node = new AsmRelExp;
// TODO
return node;
}
/**
* Parses an AsmShiftExp
*
* $(GRAMMAR $(RULEDEF asmShiftExp):
* $(RULE asmAddExp) (($(LITERAL '<<') | $(LITERAL '>>') | $(LITERAL '>>>')) $(RULE asmAddExp))?
* ;)
*/
AsmShiftExp parseAsmShiftExp()
{
auto node = new AsmShiftExp;
// TODO
return node;
}
/**
* Parses an AsmStatement
*
* $(GRAMMAR $(RULEDEF asmStatement):
* $(RULE 'asm') $(LITERAL '{') $(RULE asmInstruction)+ $(LITERAL '}')
* ;)
*/
AsmStatement parseAsmStatement()
{
auto node = new AsmStatement;
// TODO
return node;
}
/**
* Parses an AsmTypePrefix
*
* $(GRAMMAR $(RULEDEF asmTypePrefix):
* $(LITERAL Identifier) $(LITERAL Identifier)
* | $(LITERAL 'byte') $(LITERAL Identifier)
* | $(LITERAL 'short') $(LITERAL Identifier)
* | $(LITERAL 'int') $(LITERAL Identifier)
* | $(LITERAL 'float') $(LITERAL Identifier)
* | $(LITERAL 'double') $(LITERAL Identifier)
* | $(LITERAL 'real') $(LITERAL Identifier)
* ;)
*/
AsmTypePrefix parseAsmTypePrefix()
{
auto node = new AsmTypePrefix;
// TODO
return node;
}
/**
* Parses an AsmUnaExp
*
* $(GRAMMAR $(RULEDEF asmUnaExp):
* $(RULE asmTypePrefix) $(RULE asmExp)
* | $(LITERAL Identifier) $(RULE asmExp)
* | $(LITERAL '+') $(RULE asmUnaExp)
* | $(LITERAL '-') $(RULE asmUnaExp)
* | $(LITERAL '!') $(RULE asmUnaExp)
* | $(LITERAL '~') $(RULE asmUnaExp)
* | $(RULE asmPrimaryExp)
* ;)
*/
AsmUnaExp parseAsmUnaExp()
{
auto node = new AsmUnaExp;
// TODO
return node;
}
/**
* Parses an AsmXorExp
*
* $(GRAMMAR $(RULEDEF asmXorExp):
* $(RULE asmAndExp) ($(LITERAL '^') $(RULE asmAndExp))?
* ;)
*/
AsmXorExp parseAsmXorExp()
{
auto node = new AsmXorExp;
// TODO
return node;
}
/**
* Parses an AssertExpression
*
* $(GRAMMAR $(RULEDEF assertExpression):
* $(LITERAL 'assert') $(LITERAL '$(LPAREN)') $(RULE assignExpression) ($(LITERAL ',') $(RULE assignExpression))? $(LITERAL '$(RPAREN)')
* ;)
*/
AssertExpression parseAssertExpression()
{
auto node = new AssertExpression;
expect(TokenType.assert_);
expect(TokenType.lParen);
node.assertion = parseAssignExpression();
if (currentIs(TokenType.comma))
{
advance();
node.message = parseAssignExpression();
}
expect(TokenType.rParen);
return node;
}
/**
* Parses an AssertStatement
*
* $(GRAMMAR $(RULEDEF assertStatement):
* $(RULE assertExpression) $(LITERAL ';')
* ;)
*/
AssertStatement parseAssertStatement()
{
auto node = new AssertStatement;
node.assertExpression = parseAssertExpression();
expect(TokenType.semicolon);
return node;
}
/**
* Parses an AssignExpression
*
* $(GRAMMAR $(RULEDEF assignExpression):
* $(RULE ternaryExpression) ($(RULE assignOperator) $(RULE assignExpression))?
* ;
*$(RULEDEF assignOperator):
* $(LITERAL '=')
* | $(LITERAL '>>>=')
* | $(LITERAL '>>=')
* | $(LITERAL '<<=')
* | $(LITERAL '+=')
* | $(LITERAL '-=')
* | $(LITERAL '*=')
* | $(LITERAL '%=')
* | $(LITERAL '&=')
* | $(LITERAL '/=')
* | $(LITERAL '|=')
* | $(LITERAL '^^=')
* | $(LITERAL '^=')
* | $(LITERAL '~=')
* ;)
*/
AssignExpression parseAssignExpression()
{
auto node = new AssignExpression;
node.ternaryExpression = parseTernaryExpression();
if (currentIsOneOf(TokenType.assign, TokenType.unsignedShiftRightEqual,
TokenType.shiftRightEqual, TokenType.shiftLeftEqual,
TokenType.plusEqual, TokenType.minusEqual, TokenType.mulEqual,
TokenType.modEqual, TokenType.bitAndEqual, TokenType.divEqual,
TokenType.bitOrEqual, TokenType.powEqual, TokenType.xorEqual,
TokenType.catEqual))
{
node.operator = advance().type;
node.assignExpression = parseAssignExpression();
}
return node;
}
/**
* Parses an AssignStatement
*
* $(GRAMMAR $(RULEDEF assignStatement):
* $(RULE unaryExpression) $(RULE assignOperator) $(RULE assignExpression) ($(LITERAL ',') $(RULE unaryExpression) $(RULE assignOperator) $(RULE assignExpression))* $(LITERAL ';')
* | $(RULE preIncDecExpression) $(LITERAL ';')
* | $(RULE postIncDecExpression) $(LITERAL ';')
* ;)
*/
AssignStatement parseAssignStatement()
{
auto node = new AssignStatement;
// TODO
return node;
}
/**
* Parses an AssocArrayLiteral
*
* $(GRAMMAR $(RULEDEF assocArrayLiteral):
* $(LITERAL '[') $(RULE keyValuePairs) $(LITERAL ']')
* ;)
*/
AssocArrayLiteral parseAssocArrayLiteral()
{
auto node = new AssocArrayLiteral;
expect(TokenType.lBracket);
node.keyValuePairs = parseKeyValuePairs();
expect(TokenType.rBracket);
return node;
}
/**
* Parses an AtAttribute
*
* $(GRAMMAR $(RULEDEF atAttribute):
* $(LITERAL '@') ($(LITERAL Identifier) | $(LITERAL '$(LPAREN)') $(RULE argumentList) $(LITERAL '$(RPAREN)') | $(RULE functionCallExpression))
* ;)
*/
AtAttribute parseAtAttribute()
{
auto node = new AtAttribute;
// TODO
return node;
}
/**
* Parses an Attribute
*
* $(GRAMMAR $(RULEDEF attribute):
* $(RULE linkageAttribute)
* | $(RULE alignAttribute)
* | $(RULE pragmaExpression)
* | $(RULE deprecated)
* | $(RULE atAttribute)
* | $(LITERAL 'private')
* | $(LITERAL 'package')
* | $(LITERAL 'protected')
* | $(LITERAL 'public')
* | $(LITERAL 'export')
* | $(LITERAL 'extern')
* | $(LITERAL 'final')
* | $(LITERAL 'synchronized')
* | $(LITERAL 'override')
* | $(LITERAL 'abstract')
* | $(LITERAL 'const')
* | $(LITERAL 'auto')
* | $(LITERAL 'scope')
* | $(LITERAL 'gshared')
* | $(LITERAL 'shared')
* | $(LITERAL 'immutable')
* | $(LITERAL 'inout')
* | $(LITERAL 'static')
* | $(LITERAL 'pure')
* | $(LITERAL 'nothrow')
* ;)
*/
Attribute parseAttribute()
{
auto node = new Attribute;
switch (current().type)
{
case TokenType.extern_:
if (peekIs(TokenType.lParen))
node.linkageAttribute = parseLinkageAttribute();
else
node.attribute = advance().type;
break;
case TokenType.align_:
node.alignAttribute = parseAlignAttribute();
break;
case TokenType.pragma_:
node.pragmaExpression = parsePragmaExpression();
break;
case TokenType.deprecated_:
node.deprecated_ = parseDeprecated();
break;
case TokenType.private_:
case TokenType.package_:
case TokenType.protected_:
case TokenType.public_:
case TokenType.export_:
case TokenType.final_:
case TokenType.synchronized_:
case TokenType.override_:
case TokenType.abstract_:
case TokenType.const_:
case TokenType.auto_:
case TokenType.scope_:
case TokenType.gshared:
case TokenType.shared_:
case TokenType.immutable_:
case TokenType.inout_:
case TokenType.static_:
case TokenType.pure_:
case TokenType.nothrow_:
node.attribute = advance().type;
break;
default:
error("Attribute expected");
return null;
}
return node;
}
/**
* Parses an AttributedDeclaration
*
* $(GRAMMAR $(RULEDEF attributedDeclaration):
* $(RULE attribute) ($(LITERAL ':') | $(RULE declaration) | $(LITERAL '{') $(RULE declaration)* $(LITERAL '}'))
* ;)
*/
AttributedDeclaration parseAttributedDeclaration()
{
auto node = new AttributedDeclaration;
node.attribute = parseAttribute();
switch (current().type)
{
case TokenType.colon:
break;
case TokenType.lBrace:
while (moreTokens() && !currentIs(TokenType.rBrace))
node.declarations ~= parseDeclaration();
expect(TokenType.rBrace);
break;
default:
node.declarations ~= parseDeclaration();
break;
}
return node;
}
/**
* Parses an AutoDeclaration
*
* $(GRAMMAR $(RULEDEF autoDeclaration):
* $(RULE storageClass) $(LITERAL Identifier) $(LITERAL '=') $(RULE initializer) ($(LITERAL ',') $(LITERAL Identifier) $(LITERAL '=') $(RULE initializer))* $(LITERAL ';')
* ;)
*/
AutoDeclaration parseAutoDeclaration()
{
auto node = new AutoDeclaration;
// TODO
return node;
}
/**
* Parses a BlockStatement
*
* $(GRAMMAR $(RULEDEF blockStatement):
* $(LITERAL '{') $(RULE declarationsAndStatements)? $(LITERAL '}')
* ;)
*/
BlockStatement parseBlockStatement()
{
auto node = new BlockStatement();
expect(TokenType.lBrace);
if (!currentIs(TokenType.rBrace))
node.declarationsAndStatements = parseDeclarationsAndStatements();
expect(TokenType.rBrace);
return node;
}
/**
* Parses a BodyStatement
*
* $(GRAMMAR $(RULEDEF bodyStatement):
* $(LITERAL 'body') $(RULE blockStatement)
* ;)
*/
BodyStatement parseBodyStatement()
{
auto node = new BodyStatement;
expect(TokenType.body_);
node.blockStatement = parseBlockStatement();
return node;
}
/**
* Parses a BreakStatement
*
* $(GRAMMAR $(RULEDEF breakStatement):
* $(LITERAL 'break') $(LITERAL Identifier)? $(LITERAL ';')
* ;)
*/
BreakStatement parseBreakStatement()
{
expect(TokenType.break_);
auto node = new BreakStatement;
switch (current().type)
{
case TokenType.identifier:
node.identifier = advance();
expect(TokenType.semicolon);
break;
case TokenType.semicolon:
advance();
break;
default:
error("Identifier or semicolon expected following \"break\"");
return null;
}
return node;
}
/**
* Parses a BaseClass
*
* $(GRAMMAR $(RULEDEF baseClass):
* $(RULE typeofExpression) ($(LITERAL '.') $(RULE identifierOrTemplateChain))?
* | $(RULE identifierOrTemplateChain)
* ;)
*/
BaseClass parseBaseClass()
{
auto node = new BaseClass;
if (currentIs(TokenType.typeof_))
{
node.typeofExpression = parseTypeofExpression();
expect(TokenType.dot);
}
node.identifierOrTemplateChain = parseIdentifierOrTemplateChain();
return node;
}
/**
* Parses a BaseClassList
*
* $(GRAMMAR $(RULEDEF baseClassList):
* $(RULE baseClass) ($(LITERAL ',') $(RULE baseClass))*
* ;)
*/
BaseClassList parseBaseClassList()
{
auto node = new BaseClassList;
do
node.baseClasses ~= parseBaseClass();
while(currentIs(TokenType.comma));
return node;
}
/**
* Parses an BuiltinType
*
* $(GRAMMAR $(RULEDEF builtinType):
* $(LITERAL 'bool')
* | $(LITERAL 'byte')
* | $(LITERAL 'ubyte')
* | $(LITERAL 'short')
* | $(LITERAL 'ushort')
* | $(LITERAL 'int')
* | $(LITERAL 'uint')
* | $(LITERAL 'long')
* | $(LITERAL 'ulong')
* | $(LITERAL 'char')
* | $(LITERAL 'wchar')
* | $(LITERAL 'dchar')
* | $(LITERAL 'float')
* | $(LITERAL 'double')
* | $(LITERAL 'real')
* | $(LITERAL 'ifloat')
* | $(LITERAL 'idouble')
* | $(LITERAL 'ireal')
* | $(LITERAL 'cfloat')
* | $(LITERAL 'cdouble')
* | $(LITERAL 'creal')
* | $(LITERAL 'void')
* ;)
*/
BasicType parseBasicType()
{
auto node = new BasicType;
if (isBasicType(current().type))
node.type = advance().type;
else
{
error("Basic type expected");
return null;
}
return node;
}
/**
* Parses a CaseRangeStatement
*
* $(GRAMMAR $(RULEDEF caseRangeStatement):
* $(LITERAL 'case') $(RULE assignExpression) $(LITERAL ':') $(LITERAL '...') $(LITERAL 'case') $(RULE assignExpression) $(LITERAL ':') $(RULE declarationsAndStatements)
* ;)
*/
CaseRangeStatement parseCaseRangeStatement()
{
auto node = new CaseRangeStatement;
expect(TokenType.case_);
node.low = parseAssignExpression();
expect(TokenType.colon);
expect(TokenType.vararg);
expect(TokenType.case_);
node.high = parseAssignExpression();
expect(TokenType.colon);
node.declarationsAndStatements = parseDeclarationsAndStatements();
return node;
}
/**
* Parses an CaseStatement
*
* $(GRAMMAR $(RULEDEF caseStatement):
* $(LITERAL 'case') $(RULE argumentList) $(LITERAL ':') $(RULE declarationsAndStatements)
* ;)
*/
CaseStatement parseCaseStatement()
{
auto node = new CaseStatement;
expect(TokenType.case_);
node.argumentList = parseArgumentList();
expect(TokenType.colon);
node.declarationsAndStatements = parseDeclarationsAndStatements();
return node;
}
/**
* Parses a CastExpression
*
* $(GRAMMAR $(RULEDEF castExpression):
* $(LITERAL 'cast') $(LITERAL '$(LPAREN)') ($(RULE type) | $(RULE castQualifier))? $(LITERAL '$(RPAREN)') $(RULE unaryExpression)
* ;)
*/
CastExpression parseCastExpression()
{
auto node = new CastExpression;
expect(TokenType.cast_);
expect(TokenType.lParen);
if (isCastQualifier())
node.castQualifier = parseCastQualifier();
else
node.type = parseType();
expect(TokenType.rParen);
node.unaryExpression = parseUnaryExpression();
return node;
}
private bool isCastQualifier() const
{
switch (current().type)
{
case TokenType.const_:
return peekIsOneOf(TokenType.shared_, TokenType.rParen);
case TokenType.immutable_:
return peekIs(TokenType.rParen);
case TokenType.inout_:
return peekIsOneOf(TokenType.shared_, TokenType.rParen);
case TokenType.shared_:
return peekIsOneOf(TokenType.const_, TokenType.inout_, TokenType.rParen);
default:
return false;
}
}
/**
* Parses a CastQualifier
*
* $(GRAMMAR $(RULEDEF castQualifier):
* $(LITERAL 'const')
* | $(LITERAL 'const') $(LITERAL 'shared')
* | $(LITERAL 'immutable')
* | $(LITERAL 'inout')
* | $(LITERAL 'inout') $(LITERAL 'shared')
* | $(LITERAL 'shared')
* | $(LITERAL 'shared') $(LITERAL 'const')
* | $(LITERAL 'shared') $(LITERAL 'inout')
* ;)
*/
CastQualifier parseCastQualifier()
{
auto node = new CastQualifier;
switch (current().type)
{
case TokenType.inout_:
case TokenType.const_:
node.first = advance().type;
if (currentIs(TokenType.shared_))
node.second = advance().type;
break;
case TokenType.shared_:
node.first = advance().type;
if (currentIsOneOf(TokenType.const_, TokenType.inout_))
node.second = advance().type;
break;
case TokenType.immutable_:
node.first = advance().type;
break;
default:
error("const, immutable, inout, or shared expected");
return null;
}
return node;
}
/**
* Parses a Catch
*
* $(GRAMMAR $(RULEDEF catch):
* $(LITERAL 'catch') $(LITERAL '$(LPAREN)') $(RULE type) $(LITERAL Identifier)? $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
Catch parseCatch()
{
auto node = new Catch;
expect(TokenType.catch_);
expect(TokenType.lParen);
node.type = parseType();
if (currentIs(TokenType.identifier))
node.identifier = advance();
expect(TokenType.rParen);
node.nonEmptyStatementNoCaseNoDefault = parseNonEmptyStatementNoCaseNoDefault();
return node;
}
/**
* Parses a Catches
*
* $(GRAMMAR $(RULEDEF catches):
* $(RULE catch)+
* | $(RULE catch)* $(RULE lastCatch)
* ;)
*/
Catches parseCatches()
{
auto node = new Catches;
while (true)
{
expect(TokenType.catch_);
if (currentIs(TokenType.lParen))
{
node.catches ~= parseCatch();
if (currentIs(TokenType.catch_))
continue;
else
break;
}
else
{
node.lastCatch = parseLastCatch();
break;
}
}
return node;
}
/**
* Parses an ClassBody
*
* $(GRAMMAR $(RULEDEF classBody):
* $(LITERAL '{') $(RULE declarationOrInvariant)* $(LITERAL '}')
* ;)
*/
ClassBody parseClassBody()
{
auto node = new ClassBody;
expect(TokenType.lBrace);
while (!currentIs(TokenType.rBrace))
node.declarationOrInvariants ~= parseDeclarationOrInvariant();
expect(TokenType.rBrace);
return node;
}
/**
* Parses an ClassDeclaration
*
* $(GRAMMAR $(RULEDEF classDeclaration):
* $(LITERAL 'class') $(LITERAL Identifier) ($(RULE templateParameters) $(RULE constraint)?)? ($(LITERAL ':') $(RULE baseClassList))? $(RULE classBody)
* ;)
*/
ClassDeclaration parseClassDeclaration()
{
auto node = new ClassDeclaration;
expect(TokenType.class_);
node.name = *expect(TokenType.identifier);
if (currentIs(TokenType.lParen))
{
node.templateParameters = parseTemplateParameters();
if (currentIs(TokenType.if_))
node.constraint = parseConstraint();
}
if (currentIs(TokenType.colon))
node.superClasses = parseIdentifierList();
node.classBody = parseClassBody();
return node;
}
/**
* Parses a CmpExpression
*
* $(GRAMMAR $(RULEDEF cmpExpression):
* $(RULE shiftExpression)
* | $(RULE equalExpression)
* | $(RULE identityExpression)
* | $(RULE relExpression)
* | $(RULE inExpression)
* ;)
*/
CmpExpression parseCmpExpression()
{
auto node = new CmpExpression;
// TODO
return node;
}
/**
* Parses a CompileCondition
*
* $(GRAMMAR $(RULEDEF compileCondition):
* $(RULE versionCondition)
* | $(RULE debugCondition)
* | $(RULE staticIfCondition)
* ;)
*/
CompileCondition parseCompileCondition()
{
auto node = new CompileCondition;
switch (current().type)
{
case TokenType.version_:
node.versionCondition = parseVersionCondition();
break;
case TokenType.debug_:
node.debugCondition = parseDebugCondition();
break;
case TokenType.static_:
node.staticIfCondition = parseStaticIfCondition();
break;
default:
error(`"version", "debug", or "static" expected`);
return null;
}
return node;
}
/**
* Parses a ConditionalDeclaration
*
* $(GRAMMAR $(RULEDEF conditionalDeclaration):
* $(RULE compileCondition) ($(RULE declaration) | $(LITERAL '{') $(RULE declaration)* $(LITERAL '}')) ($(LITERAL 'else') ($(RULE declaration) | $(LITERAL '{') $(RULE declaration)* $(LITERAL '}')))?
* ;)
*/
ConditionalDeclaration parseConditionalDeclaration()
{
auto node = new ConditionalDeclaration;
// TODO
return node;
}
/**
* Parses an ConditionalStatement
*
* $(GRAMMAR $(RULEDEF conditionalStatement):
* $(RULE compileCondition) $(RULE nonEmptyStatementNoCaseNoDefault) ($(LITERAL 'else') $(RULE nonEmptyStatementNoCaseNoDefault))?
* ;)
*/
ConditionalStatement parseConditionalStatement()
{
auto node = new ConditionalStatement;
// TODO
return node;
}
/**
* Parses an Constraint
*
* $(GRAMMAR $(RULEDEF constraint):
* $(LITERAL 'if') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)')
* ;)
*/
Constraint parseConstraint()
{
auto node = new Constraint;
expect(TokenType.if_);
expect(TokenType.lParen);
node.expression = parseExpression();
expect(TokenType.rParen);
return node;
}
/**
* Parses a Constructor
*
* $(GRAMMAR $(RULEDEF constructor):
* $(LITERAL 'this') $(RULE parameters) $(RULE functionBody)
* ;)
*/
Constructor parseConstructor()
{
auto node = new Constructor;
expect(TokenType.this_);
node.parameters = parseParameters();
node.functionBody = parseFunctionBody();
return node;
}
/**
* Parses an ContinueStatement
*
* $(GRAMMAR $(RULEDEF continueStatement):
* $(LITERAL 'continue') $(LITERAL Identifier)? $(LITERAL ';')
* ;)
*/
ContinueStatement parseContinueStatement()
{
expect(TokenType.continue_);
auto node = new ContinueStatement;
switch (current().type)
{
case TokenType.identifier:
node.identifier = advance();
expect(TokenType.semicolon);
break;
case TokenType.semicolon:
advance();
break;
default:
error(`Identifier or semicolon expected following "continue"`);
return null;
}
return node;
}
/**
* Parses a DebugCondition
*
* $(GRAMMAR $(RULEDEF debugCondition):
* $(LITERAL 'debug') ($(LITERAL '$(LPAREN)') ($(LITERAL IntegerLiteral) | $(LITERAL Identifier)) $(LITERAL '$(RPAREN)'))?
* ;)
*/
DebugCondition parseDebugCondition()
{
auto node = new DebugCondition;
expect(TokenType.debug_);
if (currentIs(TokenType.lParen))
{
advance();
node.hasIdentifierOrInteger = true;
if (currentIsOneOf(TokenType.intLiteral, TokenType.identifier))
node.identifierOrInteger = advance();
else
{
error(`Integer literal or identifier expected`);
return null;
}
expect(TokenType.rParen);
}
else
node.hasIdentifierOrInteger = false;
return node;
}
/**
* Parses a DebugSpecification
*
* $(GRAMMAR $(RULEDEF debugSpecification):
* $(LITERAL 'debug') $(LITERAL '=') ($(LITERAL Identifier) | $(LITERAL IntegerLiteral)) $(LITERAL ';')
* ;)
*/
DebugSpecification parseDebugSpecification()
{
auto node = new DebugSpecification;
expect(TokenType.debug_);
expect(TokenType.assign);
if (currentIsOneOf(TokenType.identifier, TokenType.intLiteral))
node.identifierOrInteger = advance();
else
{
error("Integer literal or identifier expected");
return null;
}
expect(TokenType.semicolon);
return node;
}
/**
* Parses a Declaration
*
* $(GRAMMAR $(RULEDEF declaration):
* $(RULE aliasDeclaration)
* | $(RULE aliasThisDeclaration)
* | $(RULE attributedDeclaration)
* | $(RULE classDeclaration)
* | $(RULE conditionalDeclaration)
* | $(RULE constructor)
* | $(RULE destructor)
* | $(RULE enumDeclaration)
* | $(RULE functionDeclaration)
* | $(RULE importDeclaration)
* | $(RULE interfaceDeclaration)
* | $(RULE mixinDeclaration)
* | $(RULE pragmaDeclaration)
* | $(RULE sharedStaticConstructor)
* | $(RULE sharedStaticDestructor)
* | $(RULE staticAssertDeclaration)
* | $(RULE staticConstructor)
* | $(RULE staticDestructor)
* | $(RULE structDeclaration)
* | $(RULE templateDeclaration)
* | $(RULE unionDeclaration)
* | $(RULE unittest)
* | $(RULE variableDeclaration)
* ;)
*/
Declaration parseDeclaration()
{
auto node = new Declaration;
switch (current().type)
{
case TokenType.alias_:
if (startsWith(TokenType.alias_, TokenType.identifier, TokenType.this_))
node.aliasThisDeclaration = parseAliasThisDeclaration();
else
node.aliasDeclaration = parseAliasDeclaration();
break;
case TokenType.class_:
node.classDeclaration = parseClassDeclaration();
break;
case TokenType.this_:
node.constructor = parseConstructor();
break;
case TokenType.tilde:
node.destructor = parseDestructor();
break;
case TokenType.enum_:
node.enumDeclaration = parseEnumDeclaration();
break;
case TokenType.import_:
node.importDeclaration = parseImportDeclaration();
break;
case TokenType.interface_:
node.interfaceDeclaration = parseInterfaceDeclaration();
break;
case TokenType.mixin_:
node.mixinDeclaration = parseMixinDeclaration();
break;
case TokenType.pragma_:
node.pragmaDeclaration = parsePragmaDeclaration();
break;
case TokenType.shared_:
// TODO:
// sharedStaticConstructor shared static this
// sharedStaticDestructor shared static ~ this
// attributedDeclaration shared anything else
break;
case TokenType.static_:
// TODO:
// staticConstructor static this
// staticDestructor static ~
// attributedDeclaration static anything else
// conditionalDeclaration static if
break;
case TokenType.struct_:
node.structDeclaration = parseStructDeclaration();
break;
case TokenType.template_:
node.templateDeclaration = parseTemplateDeclaration();
break;
case TokenType.union_:
node.unionDeclaration = parseUnionDeclaration();
break;
case TokenType.unittest_:
node.unittest_ = parseUnittest();
break;
case TokenType.identifier:
// TODO:
// variableDeclaration
// functionDeclaration
break;
case TokenType.version_:
case TokenType.debug_:
node.conditionalDeclaration = parseConditionalDeclaration();
break;
default:
error("Declaration expected");
return null;
}
return node;
}
/**
* Parses an DeclarationsAndStatements
*
* $(GRAMMAR $(RULEDEF declarationsAndStatements):
* ($(RULE declaration) | $(RULE statementNoCaseNoDefault))+
* ;)
*/
DeclarationsAndStatements parseDeclarationsAndStatements()
{
auto node = new DeclarationsAndStatements;
// TODO
return node;
}
/**
* Parses a DeclarationOrInvariant
*
* $(GRAMMAR $(RULEDEF declarationOrInvariant):
* $(RULE declaration)
* | $(RULE invariant)
* ;)
*/
DeclarationOrInvariant parseDeclarationOrInvariant()
{
auto node = new DeclarationOrInvariant;
if (currentIs(TokenType.invariant_))
node.invariant_ = parseInvariant();
else
node.declaration = parseDeclaration();
return node;
}
/**
* Parses a Declarator
*
* $(GRAMMAR $(RULEDEF declarator):
* $(LITERAL Identifier) $(RULE declaratorSuffix)? ($(LITERAL '=') $(RULE initializer))?
* ;)
*/
Declarator parseDeclarator()
{
auto node = new Declarator;
node.identifier = *expect(TokenType.identifier);
if (currentIs(TokenType.lBracket))
node.declaratorSuffix = parseDeclaratorSuffix();
if (currentIs(TokenType.assign))
{
advance();
node.initializer = parseInitializer();
}
return node;
}
/**
* Parses a DeclaratorSuffix
*
* $(GRAMMAR $(RULEDEF declaratorSuffix):
* $(LITERAL '[') ($(RULE type) | $(RULE assignExpression))? $(LITERAL ']')
* ;)
*/
DeclaratorSuffix parseDeclaratorSuffix()
{
auto node = new DeclaratorSuffix;
// TODO
return node;
}
/**
* Parses a DefaultStatement
*
* $(GRAMMAR $(RULEDEF defaultStatement):
* $(LITERAL 'default') $(LITERAL ':') $(RULE declarationsAndStatements)
* ;)
*/
DefaultStatement parseDefaultStatement()
{
auto node = new DefaultStatement;
expect(TokenType.default_);
expect(TokenType.colon);
node.declarationsAndStatements = parseDeclarationsAndStatements();
return node;
}
/**
* Parses an DeleteExpression
*
* $(GRAMMAR $(RULEDEF deleteExpression):
* $(LITERAL 'delete') $(RULE unaryExpression)
* ;)
*/
DeleteExpression parseDeleteExpression()
{
auto node = new DeleteExpression;
// TODO
return node;
}
/**
* Parses a DeleteStatement
*
* $(GRAMMAR $(RULEDEF deleteStatement):
* $(RULE deleteExpression) $(LITERAL ';')
* ;)
*/
DeleteStatement parseDeleteStatement()
{
auto node = new DeleteStatement;
node.deleteExpression = parseDeleteExpression();
expect(TokenType.semicolon);
return node;
}
/**
* Parses a Deprecated attribute
*
* $(GRAMMAR $(RULEDEF deprecated):
* $(LITERAL 'deprecated') ($(LITERAL '$(LPAREN)') $(RULE assignExpression) $(LITERAL '$(RPAREN)'))?
* ;)
*/
Deprecated parseDeprecated()
{
auto node = new Deprecated;
expect(TokenType.deprecated_);
if (currentIs(TokenType.lParen))
{
advance();
node.assignExpression = parseAssignExpression();
expect(TokenType.rParen);
}
return node;
}
/**
* Parses a Destructor
*
* $(GRAMMAR $(RULEDEF destructor):
* $(LITERAL '~') $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') $(RULE functionBody)
* ;)
*/
Destructor parseDestructor()
{
auto node = new Destructor;
expect(TokenType.tilde);
expect(TokenType.this_);
expect(TokenType.lParen);
expect(TokenType.rParen);
node.functionBody = parseFunctionBody();
return node;
}
/**
* Parses a DoStatement
*
* $(GRAMMAR $(RULEDEF doStatement):
* $(LITERAL 'do') $(RULE nonEmptyStatementNoCaseNoDefault) $(LITERAL 'while') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)') $(LITERAL ';')
* ;)
*/
DoStatement parseDoStatement()
{
auto node = new DoStatement;
expect(TokenType.do_);
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
expect(TokenType.while_);
expect(TokenType.lParen);
node.expression = parseExpression();
expect(TokenType.rParen);
expect(TokenType.semicolon);
return node;
}
/**
* Parses an EnumBody
*
* $(GRAMMAR $(RULEDEF enumBody):
* $(LITERAL ';')
* | $(LITERAL '{') $(RULE enumMember) ($(LITERAL ',') $(RULE enumMember)?)* $(LITERAL '}')
* ;)
*/
EnumBody parseEnumBody()
{
auto node = new EnumBody;
if (!currentIs(TokenType.semicolon))
{
expect (TokenType.lBrace);
while (moreTokens())
{
if (!currentIs(TokenType.comma))
node.enumMembers ~= parseEnumMember();
if (currentIs(TokenType.comma))
continue;
else if (currentIs(TokenType.rBrace))
break;
else
{
error(`",", "}" or enum member expected`);
goto ret;
}
}
expect (TokenType.rBrace);
}
ret:
return node;
}
/**
* Parses an EnumDeclaration
*
* $(GRAMMAR $(RULEDEF enumDeclaration):
* $(LITERAL 'enum') $(LITERAL Identifier)? ($(LITERAL ':') $(RULE type))? $(RULE enumBody)
* ;)
*/
EnumDeclaration parseEnumDeclaration()
{
auto node = new EnumDeclaration;
expect(TokenType.enum_);
if (currentIs(TokenType.identifier))
node.identifier = advance();
if (currentIs(TokenType.colon))
{
advance();
node.type = parseType();
}
node.enumBody = parseEnumBody();
return node;
}
/**
* Parses an EnumMember
*
* $(GRAMMAR $(RULEDEF enumMember):
* $(LITERAL Identifier)
* | ($(LITERAL Identifier) | $(RULE type)) $(LITERAL '=') $(RULE assignExpression)
* ;)
*/
EnumMember parseEnumMember()
{
auto node = new EnumMember;
// TODO
return node;
}
/**
* Parses an EqualExpression
*
* $(GRAMMAR $(RULEDEF equalExpression):
* $(RULE shiftExpression) ($(LITERAL '==') | $(LITERAL '!=')) $(RULE shiftExpression)
* ;)
*/
EqualExpression parseEqualExpression()
{
auto node = new EqualExpression;
// TODO
return node;
}
/**
* Parses an Expression
*
* $(GRAMMAR $(RULEDEF expression):
* $(RULE assignExpression) ($(LITERAL ',') $(RULE assignExpression))*
* ;)
*/
Expression parseExpression()
{
auto node = new Expression;
// TODO
return node;
}
/**
* Parses an FinalSwitchStatement
*
* $(GRAMMAR $(RULEDEF finalSwitchStatement):
* $(LITERAL 'final') $(RULE switchStatement)
* ;)
*/
FinalSwitchStatement parseFinalSwitchStatement()
{
auto node = new FinalSwitchStatement;
// TODO
return node;
}
/**
* Parses a Finally
*
* $(GRAMMAR $(RULEDEF finally):
* $(LITERAL 'finally') $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
Finally parseFinally()
{
auto node = new Finally;
// TODO
return node;
}
/**
* Parses a ForStatement
*
* $(GRAMMAR $(RULEDEF forStatement):
* $(LITERAL 'for') $(LITERAL '$(LPAREN)') $(RULE declarationOrStatement) $(RULE expression)? $(LITERAL ';') $(RULE expression)? $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
ForStatement parseForStatement()
{
auto node = new ForStatement;
// TODO
return node;
}
/**
* Parses a ForeachRangeStatement
*
* $(GRAMMAR $(RULEDEF foreachRangeStatement):
* $(LITERAL 'foreach') $(LITERAL '$(LPAREN)') $(RULE foreachType) $(LITERAL ';') $(RULE expression) $(LITERAL '..') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
ForeachRangeStatement parseForeachRangeStatement()
{
auto node = new ForeachRangeStatement;
// TODO
return node;
}
/**
* Parses a ForeachStatement
*
* $(GRAMMAR $(RULEDEF foreachStatement):
* ($(LITERAL 'foreach') | $(LITERAL 'foreach_reverse')) $(LITERAL '$(LPAREN)') $(RULE foreachTypeList) $(LITERAL ';') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
ForeachStatement parseForeachStatement()
{
auto node = new ForeachStatement;
// TODO
return node;
}
/**
* Parses a ForeachType
*
* $(GRAMMAR $(RULEDEF foreachType):
* $(LITERAL 'ref')? $(RULE type)? $(LITERAL Identifier)
* ;)
*/
ForeachType parseForeachType()
{
auto node = new ForeachType;
// TODO
return node;
}
/**
* Parses a ForeachTypeList
*
* $(GRAMMAR $(RULEDEF foreachTypeList):
* $(RULE foreachType) ($(LITERAL ',') $(RULE foreachType))*
* ;)
*/
ForeachTypeList parseForeachTypeList()
{
auto node = new ForeachTypeList;
// TODO
return node;
}
/**
* Parses a FunctionAttribute
*
* $(GRAMMAR $(RULEDEF functionAttribute):
* $(RULE atAttribute)
* | $(LITERAL 'pure')
* | $(LITERAL 'nothrow')
* ;)
*/
FunctionAttribute parseFunctionAttribute()
{
auto node = new FunctionAttribute;
// TODO
return node;
}
/**
* Parses a FunctionBody
*
* $(GRAMMAR $(RULEDEF functionBody):
* $(RULE blockStatement)
* | ($(RULE inStatement) | $(RULE outStatement) | $(RULE outStatement) $(RULE inStatement) | $(RULE inStatement) $(RULE outStatement))? $(RULE bodyStatement)
* ;)
*/
FunctionBody parseFunctionBody()
{
auto node = new FunctionBody;
// TODO
return node;
}
/**
* Parses a FunctionCallExpression
*
* $(GRAMMAR $(RULEDEF functionCallExpression):
* $(RULE unaryExpression) $(RULE templateArguments)? $(RULE arguments)
* ;)
*/
FunctionCallExpression parseFunctionCallExpression()
{
auto node = new FunctionCallExpression;
// TODO
return node;
}
/**
* Parses a FunctionCallStatement
*
* $(GRAMMAR $(RULEDEF functionCallStatement):
* $(RULE functionCallExpression) $(LITERAL ';')
* ;)
*/
FunctionCallStatement parseFunctionCallStatement()
{
auto node = new FunctionCallStatement;
// TODO
return node;
}
/**
* Parses a FunctionDeclaration
*
* $(GRAMMAR $(RULEDEF functionDeclaration):
* $(RULE memberFunctionAttribute)* ($(RULE type) | $(LITERAL 'auto') $(LITERAL 'ref')? | $(LITERAL 'ref') $(LITERAL 'auto')?) $(LITERAL Identifier) $(RULE templateParameters) $(RULE parameters) $(RULE memberFunctionAttribute)* $(RULE constraint)? $(RULE functionBody)
* | $(RULE memberFunctionAttribute)* ($(RULE type) | $(LITERAL 'auto') $(LITERAL 'ref')? | $(LITERAL 'ref') $(LITERAL 'auto')?) $(LITERAL Identifier) $(RULE parameters) $(RULE memberFunctionAttribute)* ($(RULE functionBody) | $(LITERAL ';'))
* ;)
*/
FunctionDeclaration parseFunctionDeclaration()
{
auto node = new FunctionDeclaration;
// TODO
return node;
}
/**
* Parses an FunctionLiteralExpression
*
* $(GRAMMAR $(RULEDEF functionLiteralExpression):
* (($(LITERAL 'function') | $(LITERAL 'delegate')) $(RULE type)?)? ($(RULE parameters) $(RULE functionAttribute)*)? $(RULE functionBody)
* ;)
*/
FunctionLiteralExpression parseFunctionLiteralExpression()
{
auto node = new FunctionLiteralExpression;
// TODO
return node;
}
/**
* Parses an GotoStatement
*
* $(GRAMMAR $(RULEDEF gotoStatement):
* $(LITERAL 'goto') ($(LITERAL Identifier) | $(LITERAL 'default') | $(LITERAL 'case') $(RULE expression)?) $(LITERAL ';')
* ;)
*/
GotoStatement parseGotoStatement()
{
auto node = new GotoStatement;
// TODO
return node;
}
/**
* Parses an IdentifierChain
*
* $(GRAMMAR $(RULEDEF identifierChain):
* $(LITERAL Identifier) ($(LITERAL '.') $(LITERAL Identifier))*
* ;)
*/
IdentifierChain parseIdentifierChain()
{
auto node = new IdentifierChain;
while (true)
{
node.identifiers ~= *expect(TokenType.identifier);
if (currentIs(TokenType.dot))
{
advance();
continue;
}
else
break;
}
return node;
}
unittest
{
auto input = cast(ubyte[]) "abcde.frocegu.creou.faowe"c;
LexerConfig config;
auto tokens = byToken(input, config);
Parser p;
p.fileName = "test";
p.tokens = tokens.array();
auto chain = p.parseIdentifierChain();
assert (chain.identifiers == ["abcde", "frocegu", "creou", "faowe"]);
}
/**
* Parses an IdentifierList
*
* $(GRAMMAR $(RULEDEF identifierList):
* $(LITERAL Identifier) ($(LITERAL ',') $(LITERAL Identifier))*
* ;)
*/
IdentifierList parseIdentifierList()
{
auto node = new IdentifierList;
while (true)
{
node.identifiers ~= *expect(TokenType.identifier);
if (currentIs(TokenType.comma))
{
advance();
continue;
}
else
break;
}
return node;
}
/**
* Parses an IdentifierOrTemplateChain
*
* $(GRAMMAR $(RULEDEF identifierOrTemplateChain):
* $(RULE identifierOrTemplateInstance) ($(LITERAL '.') $(RULE identifierOrTemplateInstance))*
* ;)
*/
IdentifierOrTemplateChain parseIdentifierOrTemplateChain()
{
auto node = new IdentifierOrTemplateChain;
// TODO
return node;
}
/**
* Parses an IdentifierOrTemplateInstance
*
* $(GRAMMAR $(RULEDEF identifierOrTemplateInstance):
* $(LITERAL Identifier)
* | $(RULE templateInstance)
* ;)
*/
IdentifierOrTemplateInstance parseIdentifierOrTemplateInstance()
{
auto node = new IdentifierOrTemplateInstance;
// TODO
return node;
}
/**
* Parses an IdentityExpression
*
* $(GRAMMAR $(RULEDEF identityExpression):
* $(RULE shiftExpression) ($(LITERAL 'is') | $(LITERAL '!') $(LITERAL 'is')) $(RULE shiftExpression)
* ;)
*/
IdentityExpression parseIdentityExpression()
{
auto node = new IdentityExpression;
// TODO
return node;
}
/**
* Parses an IfStatement
*
* $(GRAMMAR $(RULEDEF ifStatement):
* $(LITERAL 'if') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault) ($(LITERAL 'else') $(RULE nonEmptyStatementNoCaseNoDefault))?
* ;)
*/
IfStatement parseIfStatement()
{
auto node = new IfStatement;
// TODO
return node;
}
/**
* Parses an ImportBind
*
* $(GRAMMAR $(RULEDEF importBind):
* $(LITERAL Identifier) ($(LITERAL '=') $(LITERAL Identifier))?
* ;)
*/
ImportBind parseImportBind()
{
auto node = new ImportBind;
// TODO
return node;
}
/**
* Parses an ImportBindings
*
* $(GRAMMAR $(RULEDEF importBindings):
* $(RULE singleImport) $(LITERAL ':') $(RULE importBind) ($(LITERAL ',') $(RULE importBind))*
* ;)
*/
ImportBindings parseImportBindings()
{
auto node = new ImportBindings;
// TODO
return node;
}
/**
* Parses an ImportDeclaration
*
* $(GRAMMAR $(RULEDEF importDeclaration):
* $(LITERAL 'static')? $(LITERAL 'import') $(RULE importList) $(LITERAL ';')
* ;)
*/
ImportDeclaration parseImportDeclaration()
{
auto node = new ImportDeclaration;
// TODO
return node;
}
/**
* Parses an ImportExpression
*
* $(GRAMMAR $(RULEDEF importExpression):
* $(LITERAL 'import') $(LITERAL '$(LPAREN)') $(RULE assignExpression) $(LITERAL '$(RPAREN)')
* ;)
*/
ImportExpression parseImportExpression()
{
auto node = new ImportExpression;
// TODO
return node;
}
/**
* Parses an ImportList
*
* $(GRAMMAR $(RULEDEF importList): $(RULE singleImport) ($(LITERAL ',') $(RULE importList))?
* | $(RULE importBindings)
* ;)
*/
ImportList parseImportList()
{
auto node = new ImportList;
// TODO
return node;
}
/**
* Parses an IndexExpression
*
* $(GRAMMAR $(RULEDEF indexExpression):
* $(RULE unaryExpression) $(LITERAL '[') $(RULE argumentList) $(LITERAL ']')
* ;)
*/
IndexExpression parseImportList()
{
auto node = new IndexExpression;
// TODO
return node;
}
/**
* Parses an InExpression
*
* $(GRAMMAR $(RULEDEF inExpression):
* $(RULE shiftExpression) ($(LITERAL 'in') | $(LITERAL '!') $(LITERAL 'in')) $(RULE shiftExpression)
* ;)
*/
InExpression parseInExpression()
{
auto node = new InExpression;
// TODO
return node;
}
/**
* Parses an InStatement
*
* $(GRAMMAR $(RULEDEF inStatement):
* $(LITERAL 'in') $(RULE blockStatement)
* ;)
*/
InStatement parseInStatement()
{
auto node = new InStatement;
// TODO
return node;
}
/**
* Parses an Initialize
*
* $(GRAMMAR $(RULEDEF initialize):
* $(LITERAL ';')
* | $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
Initialize parseInitialize()
{
auto node = new Initialize;
// TODO
return node;
}
/**
* Parses an Initializer
*
* $(GRAMMAR $(RULEDEF initializer):
* $(LITERAL 'void')
* | $(RULE nonVoidInitializer)
* ;)
*/
Initializer parseInitializer()
{
auto node = new Initializer;
// TODO
return node;
}
/**
* Parses an InterfaceDeclaration
*
* $(GRAMMAR $(RULEDEF interfaceDeclaration):
* $(LITERAL 'interface') $(LITERAL Identifier) ($(RULE templateParameters) $(RULE constraint)?)? ($(LITERAL ':') $(RULE baseClassList))? $(RULE structBody)
* ;)
*/
InterfaceDeclaration parseInterfaceDeclaration()
{
auto node = new InterfaceDeclaration;
return node;
}
/**
* Parses an Invariant
*
* $(GRAMMAR $(RULEDEF invariant):
* $(LITERAL 'invariant') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') $(RULE blockStatement)
* ;)
*/
Invariant parseInvariant()
{
auto node = new Invariant;
// TODO
return node;
}
/**
* Parses an IsExpression
*
* $(GRAMMAR $(RULEDEF isExpression):
* $(LITERAL'is') $(LITERAL '$(LPAREN)') ($(RULE assignExpression) | ($(RULE type) $(LITERAL Identifier)? (($(LITERAL ':') | '==') $(RULE typeSpecialization) ($(LITERAL ',') $(RULE templateParameterList))?)?)) $(LITERAL '$(RPAREN)')
* ;)
*/
IsExpression parseIsExpression()
{
auto node = new IsExpression;
// TODO
return node;
}
/**
* Parses a KeyValuePair
*
* $(GRAMMAR $(RULEDEF keyValuePair):
* $(RULE assignExpression) $(LITERAL ':') $(RULE assignExpression)
* ;)
*/
KeyValuePair parseKeyValuePair()
{
auto node = new KeyValuePair;
// TODO
return node;
}
/**
* Parses KeyValuePairs
*
* $(GRAMMAR $(RULEDEF keyValuePairs):
* $(RULE keyValuePair) ($(LITERAL ',') $(RULE keyValuePair))*
* ;)
*/
KeyValuePairs parseKeyValuePairs()
{
auto node = new KeyValuePairs;
// TODO
return node;
}
/**
* Parses a LabeledStatement
*
* $(GRAMMAR $(RULEDEF labeledStatement):
* $(LITERAL Identifier) $(LITERAL ':') $(RULE statement)
* ;)
*/
LabeledStatement parseLabeledStatement()
{
auto node = new LabeledStatement;
node.identifier = *expect(TokenType.identifier);
expect(TokenType.colon);
node.statement = parseStatement();
return node;
}
/**
* Parses a LambdaExpression
*
* $(GRAMMAR $(RULEDEF lambdaExpression):
* ($(LITERAL Identifier) | $(RULE parameters) $(RULE functionAttribute)* ) $(LITERAL '=>') $(RULE assignExpression)
* ;)
*/
LambdaExpression parseLambdaExpression()
{
auto node = new LambdaExpression;
// TODO
return node;
}
/**
* Parses a LastCatch
*
* $(GRAMMAR $(RULEDEF lastCatch):
* $(LITERAL 'catch') $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
LastCatch parseLastCatch()
{
auto node = new LastCatch;
// TODO
return node;
}
/**
* Parses a LinkageAttribute
*
* $(GRAMMAR $(RULEDEF linkageAttribute):
* $(LITERAL 'extern') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) $(LITERAL '++')? $(LITERAL '$(RPAREN)')
* ;)
*/
LinkageAttribute parseLinkageAttribute()
{
auto node = new LinkageAttribute;
expect(TokenType.extern_);
expect(TokenType.lParen);
node.identifier = *expect(TokenType.identifier);
if (currentIs(TokenType.increment))
{
advance();
node.hasPlusPlus = true;
}
expect(TokenType.rParen);
return node;
}
/**
* Parses a MemberFunctionAttribute
*
* $(GRAMMAR $(RULEDEF memberFunctionAttribute):
* $(RULE functionAttribute)
* | $(LITERAL 'immutable')
* | $(LITERAL 'inout')
* | $(LITERAL 'shared')
* | $(LITERAL 'const')
* ;)
*/
MemberFunctionAttribute parseMemberFunctionAttribute()
{
auto node = new MemberFunctionAttribute;
// TODO
return node;
}
/**
* Parses a MixinDeclaration
*
* $(GRAMMAR $(RULEDEF mixinDeclaration):
* $(RULE mixinExpression) $(LITERAL ';')
* ;)
*/
MixinDeclaration parseMixinDeclaration()
{
auto node = new MixinDeclaration;
node.mixinExpression = parseMixinExpression();
expect(TokenType.semicolon);
return node;
}
/**
* Parses a MixinExpression
*
* $(GRAMMAR $(RULEDEF mixinExpression):
* $(LITERAL 'mixin') $(LITERAL '$(LPAREN)') $(RULE assignExpression) $(LITERAL '$(RPAREN)')
* ;)
*/
MixinExpression parseMixinExpression()
{
auto node = new MixinExpression;
// TODO
return node;
}
/**
* Parses a MixinTemplateName
*
* $(GRAMMAR $(RULEDEF mixinTemplateName):
* ($(RULE typeofExpression)? $(LITERAL '.'))? $(RULE identifierOrTemplateChain)
* ;)
*/
MixinTemplateName parseMixinTemplateName()
{
auto node = new MixinTemplateName;
// TODO
return node;
}
/**
* Parses a Module
*
* $(GRAMMAR $(RULEDEF module):
* $(RULE moduleDeclaration)? $(RULE declaration)*
* ;)
*/
Module parseModule()
{
Module m = new Module;
while (index < tokens.length)
{
switch (tokens[index].type)
{
case TokenType.module_:
if (m.moduleDeclaration is null)
m.moduleDeclaration = parseModuleDeclaration();
else
error("Only one module declaration is allowed per module");
break;
default:
m.declarations ~= parseDeclaration();
}
}
return m;
}
/**
* Parses a ModuleDeclaration
*
* $(GRAMMAR $(RULEDEF moduleDeclaration):
* $(LITERAL 'module') $(RULE identifierChain) $(LITERAL ';')
* ;)
*/
ModuleDeclaration parseModuleDeclaration()
{
auto node = new ModuleDeclaration;
expect(TokenType.module_);
node.moduleName = parseIdentifierChain();
expect(TokenType.semicolon);
return node;
}
/**
* Parses a MulExpression
* $(GRAMMAR $(RULEDEF mulExpression):
* $(RULE unaryExpression)
* | $(RULE mulExpression) ($(LITERAL '*') | $(LITERAL '/') | $(LITERAL '%')) $(RULE unaryExpression)
* ;)
*/
MulExpression parseMulExpression()
{
auto node = new MulExpression;
auto left = parseUnaryExpression();
if (tokens[index] == TokenType.star || tokens[index] == TokenType.div)
{
node.operator = tokens[index++];
node.right = parseUnaryExpression();
}
return node;
}
/**
* Parses an NewAnonClassExpression
*
* $(GRAMMAR $(RULEDEF newAnonClassExpression):
* $(LITERAL 'new') $(RULE arguments)? $(LITERAL 'class') $(RULE arguments)? $(LITERAL Identifier) $(RULE identifierList)? $(RULE classBody)
* ;)
*/
NewAnonClassExpression parseNewAnonClassExpression()
{
auto node = new NewAnonClassExpression;
// TODO
return node;
}
/**
* Parses an NewExpression
*
* $(GRAMMAR $(RULEDEF newExpression):
* $(LITERAL 'new') $(RULE type) ($(LITERAL '[') $(RULE assignExpression) $(LITERAL ']') | $(RULE arguments))?
* | $(RULE newAnonClassExpression)
* ;)
*/
NewExpression parseNewExpression()
{
auto node = new NewExpression;
// TODO
return node;
}
/**
* Parses an NonEmptyStatement
*
* $(GRAMMAR $(RULEDEF nonEmptyStatement):
* $(RULE nonEmptyStatementNoCaseNoDefault)
* | $(RULE caseStatement)
* | $(RULE caseRangeStatement)
* | $(RULE defaultStatement)
* ;)
*/
NonEmptyStatement parseNonEmptyStatement()
{
auto node = new NonEmptyStatement;
return node;
}
/**
* Parses an NonEmptyStatementNoCaseNoDefault
*
* $(GRAMMAR $(RULEDEF nonEmptyStatementNoCaseNoDefault):
* $(RULE labeledStatement)
* | $(RULE blockStatement)
* | $(RULE assignStatement)
* | $(RULE ifStatement)
* | $(RULE whileStatement)
* | $(RULE doStatement)
* | $(RULE forStatement)
* | $(RULE foreachStatement)
* | $(RULE switchStatement)
* | $(RULE finalSwitchStatement)
* | $(RULE continueStatement)
* | $(RULE breakStatement)
* | $(RULE returnStatement)
* | $(RULE gotoStatement)
* | $(RULE withStatement)
* | $(RULE synchronizedStatement)
* | $(RULE tryStatement)
* | $(RULE throwStatement)
* | $(RULE scopeGuardStatement)
* | $(RULE asmStatement)
* | $(RULE foreachRangeStatement)
* | $(RULE conditionalStatement)
* | $(RULE staticAssertStatement)
* | $(RULE assertStatement)
* | $(RULE templateMixinStatement)
* | $(RULE versionSpecification)
* | $(RULE debugSpecification)
* | $(RULE functionCallStatement)
* | $(RULE deleteStatement)
* ;)
*/
NonEmptyStatementNoCaseNoDefault parseNonEmptyStatementNoCaseNoDefault()
{
auto node = new NonEmptyStatementNoCaseNoDefault;
// TODO
return node;
}
/**
* Parses a NonVoidInitializer
*
* $(GRAMMAR $(RULEDEF nonVoidInitializer):
* $(RULE assignExpression)
* | $(RULE arrayInitializer)
* | $(RULE structInitializer)
* ;)
*/
NonVoidInitializer parseNonVoidInitializer()
{
auto node = new NonVoidInitializer;
// TODO
return node;
}
/**
* Parses Operands
*
* $(GRAMMAR $(RULEDEF operands):
* $(RULE asmExp)+
* ;)
*/
Operands parseOperands()
{
auto node = new Operands;
// TODO
return node;
}
/**
* Parses an OrExpression
*
* $(GRAMMAR $(RULEDEF orExpression):
* $(RULE xorExpression)
* | $(RULE orExpression) $(LITERAL '|') $(RULE xorExpression)
* ;)
*/
OrExpression parseOrExpression()
{
auto node = new OrExpression;
// TODO
return node;
}
/**
* Parses an OrOrExpression
*
* $(GRAMMAR $(RULEDEF orOrExpression):
* $(RULE andAndExpression)
* | $(RULE orOrExpression) $(LITERAL '||') $(RULE andAndExpression)
* ;)
*/
OrOrExpression parseOrOrExpression()
{
auto node = new OrOrExpression;
// TODO
return node;
}
/**
* Parses an OutStatement
*
* $(GRAMMAR $(RULEDEF outStatement):
* $(LITERAL 'out') ($(LITERAL '$(LPAREN)') $(LITERAL Identifier) $(LITERAL '$(RPAREN)'))? $(RULE blockStatement)
* ;)
*/
OutStatement parseOutStatement()
{
auto node = new OutStatement;
// TODO
return node;
}
/**
* Parses a Parameter
*
* $(GRAMMAR $(RULEDEF parameter):
* $(RULE parameterAttribute)* $(RULE type) ($(LITERAL Identifier)? $(LITERAL '...') | ($(LITERAL Identifier) ($(LITERAL '=') $(RULE assignExpression))?))?
* ;)
*/
Parameter parseParameter()
{
auto node = new Parameter;
// TODO
return node;
}
/**
* Parses a ParameterAttribute
*
* $(GRAMMAR $(RULEDEF parameterAttribute):
* $(RULE typeConstructor)
* | $(LITERAL 'final')
* | $(LITERAL 'in')
* | $(LITERAL 'lazy')
* | $(LITERAL 'out')
* | $(LITERAL 'ref')
* | $(LITERAL 'scope')
* | $(LITERAL 'auto')
* ;)
*/
ParameterAttribute parseParameterAttribute()
{
auto node = new ParameterAttribute;
// TODO
return node;
}
/**
* Parses Parameters
*
* $(GRAMMAR $(RULEDEF parameters):
* $(LITERAL '$(LPAREN)') (($(RULE parameter) ($(LITERAL ',') $(RULE parameter))*)? ($(LITERAL ',') $(LITERAL '...'))? | $(LITERAL '...')) $(LITERAL '$(RPAREN)')
* ;)
*/
Parameters parseParameters()
{
auto node = new Parameters;
// TODO
return node;
}
/**
* Parses a Postblit
*
* $(GRAMMAR $(RULEDEF parameters):
* $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL 'this') $(LITERAL '$(RPAREN)') $(RULE functionBody)
* ;)
*/
Postblit parsePostblit()
{
auto node = new Postblit;
// TODO
return node;
}
/**
* Parses a PostIncDecExpression
*
* $(GRAMMAR $(RULEDEF postIncDecExpression):
* $(RULE unaryExpression) ($(LITERAL '++') | $(LITERAL '--'))
* ;)
*/
PostIncDecExpression parsePostIncDecExpression()
{
auto node = new PostIncDecExpression;
// TODO
return node;
}
/**
* Parses a PowExpression
*
* $(GRAMMAR $(RULEDEF powExpression):
* $(RULE unaryExpression)
* | $(RULE powExpression) $(LITERAL '^^') $(RULE unaryExpression)
* ;)
*/
PowExpression parsePowExpression()
{
auto node = new PowExpression;
// TODO
return node;
}
/**
* Parses a PragmaDeclaration
*
* $(GRAMMAR $(RULEDEF pragmaDeclaration):
* $(RULE pragmaExpression) $(LITERAL ';')
* ;)
*/
PragmaDeclaration parsePragmaDeclaration()
{
auto node = new PragmaDeclaration;
// TODO
return node;
}
/**
* Parses a PragmaExpression
*
* $(GRAMMAR $(RULEDEF pragmaExpression):
* $(RULE 'pragma') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) ($(LITERAL ',') $(RULE argumentList))? $(LITERAL '$(RPAREN)')
* ;)
*/
PragmaExpression parsePragmaExpression()
{
auto node = new PragmaExpression;
// TODO
return node;
}
/**
* Parses a PreIncDecExpression
*
* $(GRAMMAR $(RULEDEF preIncDecExpression):
* ($(LITERAL '++') | $(LITERAL '--')) $(RULE unaryExpression)
* ;)
*/
PreIncDecExpression parsePreIncDecExpression()
{
auto node = new PreIncDecExpression;
// TODO
return node;
}
/**
* Parses a PrimaryExpression
*
* $(GRAMMAR $(RULEDEF primaryExpression):
* $(RULE symbol)
* | $(RULE type) $(LITERAL '.') $(LITERAL Identifier)
* | $(RULE typeofExpression)
* | $(RULE typeidExpression)
* | $(RULE arrayLiteral)
* | $(RULE assocArrayLiteral)
* | $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)')
* | $(RULE isExpression)
* | $(RULE lambdaExpression)
* | $(RULE functionLiteralExpression)
* | $(RULE traitsExpression)
* | $(RULE mixinExpression)
* | $(RULE importExpression)
* | $(LITERAL '$')
* | $(LITERAL 'this')
* | $(LITERAL 'super')
* | $(LITERAL '_null')
* | $(LITERAL '_true')
* | $(LITERAL '_false')
* | $(LITERAL '___DATE__')
* | $(LITERAL '___TIME__')
* | $(LITERAL '___TIMESTAMP__')
* | $(LITERAL '___VENDOR__')
* | $(LITERAL '___VERSION__')
* | $(LITERAL '___FILE__')
* | $(LITERAL '___LINE__')
* | $(LITERAL '___MODULE__')
* | $(LITERAL '___FUNCTION__')
* | $(LITERAL '___PRETTY_FUNCTION__')
* | $(LITERAL IntegerLiteral)
* | $(LITERAL FloatLiteral)
* | $(LITERAL StringLiteral)
* | $(LITERAL CharacterLiteral)
* ;)
*/
PrimaryExpression parsePrimaryExpression()
{
auto node = new PrimaryExpression;
// TODO
return node;
}
/**
* Parses a Register
*
* $(GRAMMAR $(RULEDEF register):
* $(LITERAL Identifier)
* | $(LITERAL Identifier) $(LITERAL '$(LPAREN)') $(RULE IntegerLiteral) $(LITERAL '$(RPAREN)')
* ;)
*/
Register parseRegister()
{
auto node = new Register;
// TODO
return node;
}
/**
* Parses a RelExpression
*
* $(GRAMMAR $(RULEDEF relExpression):
* $(RULE shiftExpression)
* | $(RULE relExpression) $(RULE relOperator) $(RULE shiftExpression)
* ;
*$(RULEDEF relOperator):
* $(LITERAL '<')
* | $(LITERAL '<=')
* | $(LITERAL '>')
* | $(LITERAL '>=')
* | $(LITERAL '!<>=')
* | $(LITERAL '!<>')
* | $(LITERAL '<>')
* | $(LITERAL '<>=')
* | $(LITERAL '!>')
* | $(LITERAL '!>=')
* | $(LITERAL '!<')
* | $(LITERAL '!<=')
* ;)
*/
RelExpression parseRelExpression()
{
auto node = new RelExpression;
// TODO
return node;
}
/**
* Parses a ReturnStatement
*
* $(GRAMMAR $(RULEDEF returnStatement):
* $(LITERAL 'return') $(RULE expression)? $(LITERAL ';')
* ;)
*/
ReturnStatement parseReturnStatement()
{
auto node = new ReturnStatement;
expect(TokenType.return_);
if (tokens[index] != TokenType.semicolon)
node.expression = parseExpression();
expect(TokenType.semicolon);
return node;
}
/**
* Parses a ScopeGuardStatement
*
* $(GRAMMAR $(RULEDEF scopeGuardStatement):
* $(LITERAL 'scope') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
ScopeGuardStatement parseScopeGuardStatement()
{
auto node = new ScopeGuardStatement;
// TODO
return node;
}
/**
* Parses a SharedStaticConstructor
*
* $(GRAMMAR $(RULEDEF sharedStaticConstructor):
* $(LITERAL 'shared') $(LITERAL 'static') $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') $(RULE functionBody)
* ;)
*/
SharedStaticConstructor parseSharedStaticConstructor()
{
auto node = new SharedStaticConstructor;
// TODO
return node;
}
/**
* Parses a SharedStaticDestructor
*
* $(GRAMMAR $(RULEDEF sharedStaticDestructor):
* $(LITERAL 'shared') $(LITERAL 'static') $(LITERAL '~') $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') $(RULE functionBody)
* ;)
*/
SharedStaticDestructor parseSharedStaticDestructor()
{
auto node = new SharedStaticDestructor;
// TODO
return node;
}
/**
* Parses a ShiftExpression
*
* $(GRAMMAR $(RULEDEF shiftExpression):
* $(RULE addExpression)
* | $(RULE shiftExpression) ($(LITERAL '<<') | $(LITERAL '>>') | $(LITERAL '>>>')) $(RULE addExpression)
* ;)
*/
ShiftExpression parseShiftExpression()
{
auto node = new ShiftExpression;
// TODO
return node;
}
/**
* Parses a SingleImport
*
* $(GRAMMAR $(RULEDEF singleImport):
* ($(LITERAL Identifier) $(LITERAL '='))? $(RULE identifierChain)
* ;)
*/
SingleImport parseSingleImport()
{
auto node = new SingleImport;
// TODO
return node;
}
/**
* Parses a Statement
*
* $(GRAMMAR $(RULEDEF statement):
* $(LITERAL ';')
* | $(RULE nonEmptyStatement)
* ;)
*/
Statement parseStatement()
{
auto node = new Statement;
if (currentIs(TokenType.semicolon))
advance();
else
node.nonEmptyStatement = parseNonEmptyStatement();
return node;
}
/**
* Parses a StatementNoCaseNoDefault
*
* $(GRAMMAR $(RULEDEF statementNoCaseNoDefault):
* $(LITERAL ';')
* | $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
StatementNoCaseNoDefault parseStatementNoCaseNoDefault()
{
auto node = new StatementNoCaseNoDefault;
if (tokens[index] != TokenType.semicolon)
node.nonEmptyStatementNoCaseNoDefault = parseNonEmptyStatementNoCaseNoDefault();
else
expect(TokenType.semicolon);
return node;
}
/**
* Parses a StaticAssertDeclaration
*
* $(GRAMMAR $(RULEDEF staticAssertDeclaration):
* $(RULE staticAssertStatement)
* ;)
*/
StaticAssertDeclaration parseStaticAssertDeclaration()
{
auto node = new StaticAssertDeclaration;
node.staticAssertStatement = parseStaticAssertStatement();
return node;
}
/**
* Parses a StaticAssertStatement
*
* $(GRAMMAR $(RULEDEF staticAssertStatement):
* $(LITERAL 'static') $(RULE assertStatement)
* ;)
*/
StaticAssertStatement parseStaticAssertStatement()
{
auto node = new StaticAssertStatement;
expect(TokenType.static_);
node.assertStatement = parseAssertStatement();
return node;
}
/**
* Parses a StaticConstructor
*
* $(GRAMMAR $(RULEDEF staticConstructor):
* $(LITERAL 'static') $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') $(RULE functionBody)
* ;)
*/
StaticConstructor parseStaticConstructor()
{
auto node = new StaticConstructor;
expect(TokenType.static_);
expect(TokenType.this_);
expect(TokenType.lParen);
expect(TokenType.rParen);
node.functionBody = parseFunctionBody();
return node;
}
/**
* Parses a StaticDestructor
*
* $(GRAMMAR $(RULEDEF staticConstructor):
* $(LITERAL 'static') $(LITERAL '~') $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') $(RULE functionBody)
* ;)
*/
StaticDestructor parseStaticDestructor()
{
auto node = new StaticDestructor;
expect(TokenType.static_);
expect(TokenType.tilde);
expect(TokenType.this_);
expect(TokenType.lParen);
expect(TokenType.rParen);
node.functionBody = parseFunctionBody();
return node;
}
/**
* Parses an StaticIfCondition
*
* $(GRAMMAR $(RULEDEF staticIfCondition):
* $(RULE 'static') $(LITERAL 'if') $(LITERAL '$(LPAREN)') $(RULE assignExpression) $(LITERAL '$(RPAREN)')
* ;)
*/
StaticIfCondition parseStaticIfCondition()
{
auto node = new StaticIfCondition;
expect(TokenType.static_);
expect(TokenType.if_);
expect(TokenType.lParen);
node.assignExpression = parseAssignExpression();
expect(TokenType.rParen);
return node;
}
/**
* Parses an StorageClass
*
* $(GRAMMAR $(RULE storageClass):
* $(RULE atAttribute)
* | $(RULE typeConstructor)
* | $(LITERAL 'abstract')
* | $(LITERAL 'auto')
* | $(LITERAL 'deprecated')
* | $(LITERAL 'enum')
* | $(LITERAL 'extern')
* | $(LITERAL 'final')
* | $(LITERAL 'nothrow')
* | $(LITERAL 'override')
* | $(LITERAL 'pure')
* | $(LITERAL '___gshared')
* | $(LITERAL 'scope')
* | $(LITERAL 'static')
* | $(LITERAL 'synchronized')
* ;)
*/
StorageClass parseStorageClass()
{
auto node = new StorageClass;
// TODO
return node;
}
/**
* Parses a StructBody
*
* $(GRAMMAR $(RULEDEF structBody):
* $(LITERAL '{') $(RULE structBodyItem)* $(LITERAL '}')
* ;)
*/
StructBody parseStructBody()
{
auto node = new StructBody;
expect(TokenType.lBrace);
while (tokens[index] != TokenType.rBrace && moreTokens())
node.structBodyItems ~= parseStructBodyItem();
expect(TokenType.rBrace);
return node;
}
/**
* Parses a StructBodyItem
*
* $(GRAMMAR $(RULEDEF structBodyItem):
* $(RULE declaration)
* | $(RULE postBlit)
* | $(RULE invariant)
* ;)
*/
StructBodyItem parseStructBodyItem()
{
auto node = new StructBodyItem;
return node;
}
/**
* Parses a StructDeclaration
*
* $(GRAMMAR $(RULEDEF structDeclaration):
* $(LITERAL 'struct') $(LITERAL Identifier) ($(RULE templateParameters) $(RULE constraint)? $(RULE structBody) | ($(RULE structBody) | $(LITERAL ';')))
* ;)
*/
StructDeclaration parseStructDeclaration()
{
auto node = new StructDeclaration;
expect(TokenType.struct_);
node.identifier = *expect(TokenType.identifier);
if (currentIs(TokenType.lParen))
{
node.templateParameters = parseTemplateParameters();
if (tokens[index] == TokenType.if_)
node.constraint = parseConstraint();
node.structBody = parseStructBody();
}
else if (currentIs(TokenType.lBrace))
{
node.structBody = parseStructBody();
}
else if (currentIs(TokenType.semicolon))
advance();
else
{
error("Template Parameters, Struct Body, or Semicolon expected");
return null;
}
return node;
}
/**
* Parses an StructInitializer
*
* $(GRAMMAR $(RULEDEF structInitializer):
* $(LITERAL '{') $(RULE structMemberInitializers)? $(LITERAL '}')
* ;)
*/
StructInitializer parseStructInitializer()
{
auto node = new StructInitializer;
expect(TokenType.lBrace);
node.structMemberInitializers = parseStructMemberInitializers();
expect(TokenType.rBrace);
return node;
}
/**
* Parses a StructMemberInitializer
*
* $(GRAMMAR $(RULEDEF structMemberInitializer):
* ($(LITERAL Identifier) $(LITERAL ':'))? $(RULE nonVoidInitializer)
* ;)
*/
StructMemberInitializer parseStructMemberInitializer()
{
auto node = new StructMemberInitializer;
if (startsWith(TokenType.identifier, TokenType.colon))
{
node.identifier = tokens[index++];
index++;
}
node.nonVoidInitializer = parseNonVoidInitializer();
return node;
}
/**
* Parses StructMemberInitializers
*
* $(GRAMMAR $(RULEDEF structMemberInitializers):
* $(RULE structMemberInitializer) ($(LITERAL ',') $(RULE structMemberInitializer)?)*
* ;)
*/
StructMemberInitializers parseStructMemberInitializers()
{
auto node = new StructMemberInitializers;
// TODO
return node;
}
/**
* Parses a SwitchBody
*
* $(GRAMMAR $(RULEDEF switchBody):
* $(LITERAL '{') $(RULE statement)+ $(LITERAL '}')
* ;)
*/
SwitchBody parseSwitchBody()
{
auto node = new SwitchBody;
expect(TokenType.lBrace);
while (moreTokens() && tokens[index] != TokenType.rBrace)
node.statements ~= parseStatement();
expect(TokenType.rBrace);
return node;
}
/**
* Parses an SwitchStatement
*
* $(GRAMMAR $(RULEDEF switchStatement):
* $(LITERAL 'switch') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE switchBody)
* ;)
*/
SwitchStatement parseSwitchStatement()
{
auto node = new SwitchStatement;
expect(TokenType.switch_);
expect(TokenType.lParen);
node.expression = parseExpression();
expect(TokenType.rParen);
node.switchBody = parseSwitchBody();
return node;
}
/**
* Parses a Symbol
*
* $(GRAMMAR $(RULEDEF symbol):
* $(LITERAL '.')? $(RULE identifierOrTemplateChain)
* ;)
*/
Symbol parseSymbol()
{
auto node = new Symbol;
if (tokens[index] == TokenType.dot)
{
node.hasDot = true;
++index;
}
node.identifierOrTemplateChain = parseIdentifierOrTemplateChain();
return node;
}
/**
* Parses an SynchronizedStatement
*
* $(GRAMMAR $(RULEDEF synchronizedStatement):
* $(LITERAL 'synchronized') ($(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)'))? $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
SynchronizedStatement parseSynchronizedStatement()
{
auto node = new SynchronizedStatement;
expect(TokenType.synchronized_);
if (tokens[index] == TokenType.lParen)
{
expect(TokenType.lParen);
node.expression = parseExpression();
expect(TokenType.rParen);
}
node.nonEmptyStatementNoCaseNoDefault = parseNonEmptyStatementNoCaseNoDefault();
return node;
}
/**
* Parses an TemplateAliasParameter
*
* $(GRAMMAR $(RULEDEF templateAliasParameter):
* $(LITERAL 'alias') $(RULE type)? $(LITERAL Identifier) ($(LITERAL ':') ($(RULE type) | $(RULE expression)))? ($(LITERAL '=') ($(RULE type) | $(RULE expression)))?
* ;)
*/
TemplateAliasParameter parseTemplateAliasParameter()
{
auto node = new TemplateAliasParameter;
// TODO
return node;
}
/**
* Parses a TemplateArgument
*
* $(GRAMMAR $(RULEDEF templateArgument):
* $(RULE type)
* | $(RULE assignExpression)
* | $(RULE symbol)
* ;)
*/
TemplateArgument parseTemplateArgument()
{
auto node = new TemplateArgument;
// TODO
return node;
}
/**
* Parses a TemplateArgumentList
*
* $(GRAMMAR $(RULEDEF templateArgumentList):
* $(RULE templateArgument) ($(LITERAL ',') $(RULE templateArgument)?)*
* ;)
*/
TemplateArgumentList parseTemplateArgumentList()
{
auto node = new TemplateArgumentList;
// TODO
return node;
}
/**
* Parses TemplateArguments
*
* $(GRAMMAR $(RULEDEF templateArguments):
* $(LITERAL '!') ($(LITERAL '$(LPAREN)') $(RULE templateArgumentList)? $(LITERAL '$(RPAREN)') | $(RULE templateSingleArgument))
* ;)
*/
TemplateArguments parseTemplateArguments()
{
auto node = new TemplateArguments;
// TODO
return node;
}
/**
* Parses an TemplateDeclaration
*
* $(GRAMMAR $(RULEDEF templateDeclaration):
* $(LITERAL 'template') $(LITERAL Identifier) $(RULE templateParameters) $(RULE constraint)? $(LITERAL '{') $(RULE declaration)+ $(LITERAL '}')
* ;)
*/
TemplateDeclaration parseTemplateDeclaration()
{
auto node = new TemplateDeclaration;
// TODO
return node;
}
/**
* Parses a TemplateInstance
*
* $(GRAMMAR $(RULEDEF templateInstance):
* $(LITERAL Identifier) $(RULE templateArguments)
* ;)
*/
TemplateInstance parseTemplateInstance()
{
auto node = new TemplateInstance;
// TODO
return node;
}
/**
* Parses a TemplateMixinStatement
*
* $(GRAMMAR $(RULEDEF templateMixinStatement):
* $(LITERAL 'mixin') $(RULE mixinTemplateName) $(RULE templateArguments)? $(LITERAL Identifier)? $(LITERAL ';')
* ;)
*/
TemplateMixinStatement parseTemplateMixinStatement()
{
auto node = new TemplateMixinStatement;
// TODO
return node;
}
/**
* Parses a TemplateParameter
*
* $(GRAMMAR $(RULEDEF templateParameter):
* $(RULE templateTypeParameter)
* | $(RULE templateValueParameter)
* | $(RULE templateAliasParameter)
* | $(RULE templateTupleParameter)
* | $(RULE templateThisParameter)
* ;)
*/
TemplateParameter parseTemplateParameter()
{
auto node = new TemplateParameter;
// TODO
return node;
}
/**
* Parses an TemplateParameterList
*
* $(GRAMMAR $(RULEDEF templateParameterList):
* $(RULE templateParameter) ($(LITERAL ',') $(RULE templateParameter)?)*
* ;)
*/
TemplateParameterList parseTemplateParameterList()
{
auto node = new TemplateParameterList;
// TODO
return node;
}
/**
* Parses TemplateParameters
*
* $(GRAMMAR $(RULEDEF templateParameters):
* $(LITERAL '$(LPAREN)') $(RULE templateParameterList)? $(LITERAL '$(RPAREN)')
* ;)
*/
TemplateParameters parseTemplateParameters()
{
auto node = new TemplateParameters;
// TODO
return node;
}
/**
* Parses an TemplateSingleArgument
*
* $(GRAMMAR $(RULEDEF templateSingleArgument):
* $(RULE basicType)
* | $(LITERAL Identifier)
* | $(LITERAL CharacterLiteral)
* | $(LITERAL StringLiteral)
* | $(LITERAL IntegerLiteral)
* | $(LITERAL FloatLiteral)
* | $(LITERAL '_true')
* | $(LITERAL '_false')
* | $(LITERAL '_null')
* | $(LITERAL 'this')
* | $(LITERAL '__DATE__')
* | $(LITERAL '__TIME__')
* | $(LITERAL '__TIMESTAMP__')
* | $(LITERAL '__VENDOR__')
* | $(LITERAL '__VERSION__')
* | $(LITERAL '__FILE__')
* | $(LITERAL '__LINE__')
* | $(LITERAL '__MODULE__')
* | $(LITERAL '__FUNCTION__')
* | $(LITERAL '__PRETTY_FUNCTION__')
* ;)
*/
TemplateSingleArgument parseTemplateSingleArgument()
{
auto node = new TemplateSingleArgument;
// TODO
return node;
}
/**
* Parses an TemplateThisParameter
*
* $(GRAMMAR $(RULEDEF templateThisParameter):
* $(LITERAL 'this') $(RULE templateTypeParameter)
* ;)
*/
TemplateThisParameter parseTemplateThisParameter()
{
auto node = new TemplateThisParameter;
// TODO
return node;
}
/**
* Parses an TemplateTupleParameter
*
* $(GRAMMAR $(RULEDEF templateTupleParameter):
* $(LITERAL Identifier) '...'
* ;)
*/
TemplateTupleParameter parseTemplateTupleParameter()
{
auto node = new TemplateTupleParameter;
// TODO
return node;
}
/**
* Parses a TemplateTypeParameter
*
* $(GRAMMAR $(RULEDEF templateTypeParameter):
* $(LITERAL Identifier) ($(LITERAL ':') $(RULE type))? ($(LITERAL '=') $(RULE type))?
* ;)
*/
TemplateTypeParameter parseTemplateTypeParameter()
{
auto node = new TemplateTypeParameter;
// TODO
return node;
}
/**
* Parses a TemplateValueParameter
*
* $(GRAMMAR $(RULEDEF templateValueParameter):
* $(RULE type) $(LITERAL Identifier) ($(LITERAL ':') $(RULE expression))? $(RULE templateValueParameterDefault)?
* ;)
*/
TemplateValueParameter parseTemplateValueParameter()
{
auto node = new TemplateValueParameter;
// TODO
return node;
}
/**
* Parses a TemplateValueParameterDefault
*
* $(GRAMMAR $(RULEDEF templateValueParameterDefault):
* $(LITERAL '=') ('__FILE__' | '__MODULE__' | '__LINE__' | '__FUNCTION__' | '__PRETTY_FUNCTION__' | $(RULE assignExpression))
* ;)
*/
TemplateValueParameterDefault parseTemplateValueParameterDefault()
{
auto node = new TemplateValueParameterDefault;
// TODO
return node;
}
/**
* Parses a TernaryExpression
*
* $(GRAMMAR $(RULEDEF ternaryExpression):
* $(RULE orOrExpression) ($(LITERAL '?') $(RULE expression) $(LITERAL ':') $(RULE ternaryExpression))?
* ;)
*/
TernaryExpression parseTernaryExpression()
{
auto node = new TernaryExpression;
node.orOrExpression = parseOrOrExpression();
if (tokens[index] == TokenType.ternary)
{
++index;
node.expression = parseExpression();
expect(TokenType.colon);
node.ternaryExpression = parseTernaryExpression();
}
return node;
}
/**
* Parses a ThrowStatement
*
* $(GRAMMAR $(RULEDEF throwStatement):
* $(LITERAL 'throw') $(RULE expression) $(LITERAL ';')
* ;)
*/
ThrowStatement parseThrowStatement()
{
auto node = new ThrowStatement;
expect(TokenType.throw_);
node.expression = parseExpression();
expect(TokenType.semicolon);
return node;
}
/**
* Parses an TraitsArgument
*
* $(GRAMMAR $(RULEDEF traitsArgument):
* $(RULE assignExpression)
* | $(RULE type)
* ;)
*/
TraitsArgument parseTraitsArgument()
{
auto node = new TraitsArgument;
// TODO
return node;
}
/**
* Parses an TraitsExpression
*
* $(GRAMMAR $(RULEDEF traitsExpression):
* $(LITERAL '__traits') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) $(LITERAL ',') $(RULE traitsArgument) ($(LITERAL ',') $(RULE traitsArgument))* $(LITERAL '$(RPAREN)')
* ;)
*/
TraitsExpression parseTraitsExpression()
{
auto node = new TraitsExpression;
// TODO
return node;
}
/**
* Parses a TryStatement
*
* $(GRAMMAR $(RULEDEF tryStatement):
* $(LITERAL 'try') $(RULE nonEmptyStatementNoCaseNoDefault) ($(RULE catches) | $(RULE catches) $(RULE finally) | $(RULE finally))
* ;)
*/
TryStatement parseTryStatement()
{
auto node = new TryStatement;
// TODO
return node;
}
/**
* Parses a Type
*
* $(GRAMMAR $(RULEDEF type):
* $(RULE typeConstructors)? $(RULE type2)
* ;)
*/
Type parseType()
{
auto node = new Type;
// TODO
return node;
}
/**
* Parses a Type2
*
* $(GRAMMAR $(RULEDEF type2):
* $(RULE type3) $(RULE typeSuffix)?
* | $(RULE type2) $(RULE typeSuffix)
* ;)
*/
Type2 parseType2()
{
auto node = new Type2;
// TODO
return node;
}
/**
* Parses a Type3
*
* $(GRAMMAR $(RULEDEF type3):
* $(RULE basicType)
* | $(RULE symbol)
* | $(RULE typeofExpression) ($(LITERAL '.') $(RULE identifierOrTemplateChain))?
* | $(RULE typeConstructor) $(LITERAL '$(LPAREN)') $(RULE type) $(LITERAL '$(RPAREN)')
* ;)
*/
Type3 parseType3()
{
auto node = new Type3;
// TODO
return node;
}
/**
* Parses a TypeConstructor
*
* $(GRAMMAR $(RULEDEF typeConstructor):
* $(LITERAL 'const')
* | $(LITERAL 'immutable')
* | $(LITERAL 'inout')
* | $(LITERAL 'shared')
* ;)
*/
TypeConstructor parseTypeConstructor()
{
auto node = new TypeConstructor;
// TODO
return node;
}
/**
* Parses TypeConstructors
*
* $(GRAMMAR $(RULEDEF typeConstructors):
* $(RULE typeConstructor)+
* ;)
*/
TypeConstructors parseTypeConstructors()
{
auto node = new TypeConstructors;
// TODO
return node;
}
/**
* Parses a TypeSpecialization
*
* $(GRAMMAR $(RULEDEF typeSpecialization):
* $(RULE type)
* | $(LITERAL 'struct')
* | $(LITERAL 'union')
* | $(LITERAL 'class')
* | $(LITERAL 'interface')
* | $(LITERAL 'enum')
* | $(LITERAL 'function')
* | $(LITERAL 'delegate')
* | $(LITERAL 'super')
* | $(LITERAL 'const')
* | $(LITERAL 'immutable')
* | $(LITERAL 'inout')
* | $(LITERAL 'shared')
* | $(LITERAL 'return')
* | $(LITERAL '___parameters')
* ;)
*/
TypeSpecialization parseTypeSpecialization()
{
auto node = new TypeSpecialization;
// TODO
return node;
}
/**
* Parses a TypeSuffix
*
* $(GRAMMAR $(RULEDEF typeSuffix):
* $(LITERAL '*')
* | $(LITERAL '[') ($(RULE type) | $(RULE assignExpression))? $(LITERAL ']')
* | ($(LITERAL 'delegate') | $(LITERAL 'function')) $(RULE parameters) $(RULE memberFunctionAttribute)*
* ;)
*/
TypeSuffix parseTypeSuffix()
{
auto node = new TypeSuffix;
// TODO
return node;
}
/**
* Parses a TypeidExpression
*
* $(GRAMMAR $(RULEDEF typeidExpression):
* $(LITERAL 'typeid') $(LITERAL '$(LPAREN)')($(RULE type) | $(RULE expression)) $(LITERAL '$(RPAREN)')
* ;)
*/
TypeidExpression parseTypeidExpression()
{
auto node = new TypeidExpression;
// TODO
return node;
}
/**
* Parses a TypeofExpression
*
* $(GRAMMAR $(RULEDEF typeofExpression):
* $(LITERAL 'typeof') $(LITERAL '$(LPAREN)')($(RULE expression) | $(LITERAL 'return')) $(LITERAL '$(RPAREN)')
* ;)
*/
TypeofExpression parseTypeofExpression()
{
auto node = new TypeofExpression;
expect(TokenType.typeof_);
expect(TokenType.lParen);
if (tokens[index] == TokenType.return_)
node.return_ = tokens[index];
else
node.expression = parseExpression();
expect(TokenType.rParen);
return node;
}
/**
* Parses a UnaryExpression
*
* $(GRAMMAR $(RULEDEF unaryExpression):
* $(RULE primaryExpression)
* | $(LITERAL '&') $(RULE unaryExpression)
* | $(LITERAL '!') $(RULE unaryExpression)
* | $(LITERAL '*') $(RULE unaryExpression)
* | $(LITERAL '+') $(RULE unaryExpression)
* | $(LITERAL '-') $(RULE unaryExpression)
* | $(LITERAL '~') $(RULE unaryExpression)
* | $(RULE newExpression)
* | $(RULE deleteExpression)
* | $(RULE castExpression)
* | $(RULE functionCallExpression)
* | $(RULE preIncDecExpression)
* | $(RULE postIncDecExpression)
* | $(RULE sliceExpression)
* | $(RULE indexExpression)
* | $(RULE unaryExpression) $(LITERAL '.') $(RULE identifierOrTemplateInstance)
* | $(RULE assertExpression)
* ;)
*/
UnaryExpression parseUnaryExpression()
{
auto node = new UnaryExpression;
// TODO
return node;
}
/**
* Parses an UnionDeclaration
*
* $(GRAMMAR $(RULEDEF unionDeclaration):
* '$(RULE union)' $(LITERAL Identifier) (($(RULE templateParameters) $(RULE constraint)? $(RULE structBody))? | ($(RULE structBody) | $(LITERAL ';')))
* ;)
*/
UnionDeclaration parseUnionDeclaration()
{
auto node = new UnionDeclaration;
// TODO
return node;
}
/**
* Parses a Unittest
*
* $(GRAMMAR $(RULEDEF unittest):
* $(LITERAL 'unittest') $(RULE blockStatement)
* ;)
*/
Unittest parseUnittest()
{
auto node = new Unittest;
expect(TokenType.unittest_);
node.blockStatement = parseBlockStatement();
return node;
}
/**
* Parses a VariableDeclaration
*
* $(GRAMMAR $(RULEDEF variableDeclaration):
* $(RULE storageClass)? $(RULE type) $(RULE declarator) ($(LITERAL ',') $(RULE declarator))* $(LITERAL ';')
* | $(RULE autoDeclaration)
* ;)
*/
VariableDeclaration parseVariableDeclaration()
{
auto node = new VariableDeclaration;
// TODO
return node;
}
/**
* Parses a VersionCondition
*
* $(GRAMMAR $(RULEDEF versionCondition):
* $(LITERAL 'version') $(LITERAL '$(LPAREN)') ($(LITERAL IntegerLiteral) | $(LITERAL Identifier) | $(LITERAL 'unittest') | $(LITERAL 'assert')) $(LITERAL '$(RPAREN)')
* ;)
*/
VersionCondition parseVersionCondition()
{
auto node = new VersionCondition;
expect(TokenType.version_);
expect(TokenType.lParen);
if (currentIsOneOf(TokenType.intLiteral, TokenType.identifier,
TokenType.unittest_, TokenType.assert_))
{
node.token = advance();
}
else
{
error(`Expected an integer literal, an identifier, "assert", or "unittest"`);
return null;
}
expect(TokenType.rParen);
return node;
}
/**
* Parses a VersionSpecification
*
* $(GRAMMAR $(RULEDEF versionSpecification):
* $(LITERAL 'version') $(LITERAL '=') ($(LITERAL Identifier) | $(LITERAL IntegerLiteral)) $(LITERAL ';')
* ;)
*/
VersionSpecification parseVersionSpecification()
{
auto node = new VersionSpecification;
expect(TokenType.version_);
expect(TokenType.assign);
if (!currentIsOneOf(TokenType.identifier, TokenType.intLiteral))
{
error("Identifier or integer literal expected");
return null;
}
node.token = advance();
expect(TokenType.semicolon);
return node;
}
/**
* Parses a WhileStatement
*
* $(GRAMMAR $(RULEDEF whileStatement):
* $(LITERAL 'while') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE statementNoCaseNoDefault)
* ;)
*/
WhileStatement parseWhileStatement()
{
auto node = new WhileStatement;
expect(TokenType.while_);
expect(TokenType.lParen);
node.expression = parseExpression();
expect(TokenType.rParen);
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
return node;
}
/**
* Parses a WithStatement
*
* $(GRAMMAR $(RULEDEF withStatement):
* $(LITERAL 'with') $(LITERAL '$(LPAREN)') ($(RULE expression) | $(RULE symbol) | $(RULE templateInstance)) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
WithStatement parseWithStatement()
{
auto node = new WithStatement;
expect(TokenType.with_);
expect(TokenType.lParen);
// TODO: magic here
expect(TokenType.rParen);
parseNonEmptyStatementNoCaseNoDefault();
return node;
}
/**
* Parses an XorExpression
*
* $(GRAMMAR $(RULEDEF xorExpression):
* $(RULE andExpression)
* | $(RULE xorExpression) $(LITERAL '^') $(RULE andExpression)
* ;)
*/
XorExpression parseXorExpression()
{
auto node = new XorExpression;
// TODO
return node;
}
void error(string message)
{
++errorCount;
import std.stdio;
stderr.writefln("%s(%d:%d): %s", fileName, tokens[index].line,
tokens[index].column, message);
while (index < tokens.length)
{
if (tokens[++index].type == TokenType.semicolon)
break;
}
}
const(Token)* peekPast(alias O, alias C)()
in
{
assert (tokens[index].type == O);
}
body
{
int depth = 1;
auto i = index;
++i;
while (index < tokens.length)
{
if (tokens[i] == O)
++depth;
else if (tokens[i] == C)
{
--depth;
++i;
if (depth <= 0)
break;
}
++i;
}
return depth == 0 ? &tokens[i] : null;
}
const(Token)* peekPastParens()
{
return peekPast!(TokenType.lParen, TokenType.rParen)();
}
const(Token)* peekPastBrackets()
{
return peekPast!(TokenType.lBracket, TokenType.rBracket)();
}
const(Token)* peekPastBraces()
{
return peekPast!(TokenType.lBrace, TokenType.rBrace)();
}
bool peekIs(TokenType t) const
{
return index + 1 < tokens.length && tokens[index + 1].type == t;
}
bool peekIsOneOf(TokenType[] types...) const
{
if (index + 1 >= tokens.length) return false;
return canFind(types, tokens[index + 1].type);
}
/**
* Returns a token of the specified type if it was the next token, otherwise
* calls the error function and returns null.
*/
const(Token)* expect(TokenType type)
{
if (tokens[index].type == type)
return &tokens[index++];
else
{
error("Expected " ~ to!string(type));
return null;
}
}
/**
* Returns: the current token
*/
Token current() const
{
return tokens[index];
}
/**
* Advances to the next token and returns the current token
*/
Token advance()
{
return tokens[index++];
}
/**
* Returns: true if the current token has the given type
*/
bool currentIs(TokenType type) const
{
return index < tokens.length && tokens[index] == type;
}
/**
* Returns: true if the current token is one of the given types
*/
bool currentIsOneOf(TokenType[] types...) const
{
return canFind(types, current().type);
}
bool startsWith(TokenType[] types...) const
{
for (size_t i = 0; i != types.length; ++i)
{
if (tokens[index + i].type != types[i])
return false;
}
return true;
}
/**
* Returns: true if there are more tokens
*/
bool moreTokens() const
{
return index < tokens.length;
}
uint errorCount;
const(Token)[] tokens;
size_t index;
string fileName;
}