Lots of DDoc changes, some parser work
This commit is contained in:
parent
4ad043085a
commit
0e58854fa9
1264
std/d/ast.d
1264
std/d/ast.d
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,7 @@
|
||||||
* LexerConfig config;
|
* LexerConfig config;
|
||||||
* config.iterStyle = IterationStyle.everything;
|
* config.iterStyle = IterationStyle.everything;
|
||||||
* config.tokenStyle = TokenStyle.source;
|
* config.tokenStyle = TokenStyle.source;
|
||||||
* config.versionNumber = 2061;
|
* config.versionNumber = 2064;
|
||||||
* config.vendorString = "Lexer Example";
|
* config.vendorString = "Lexer Example";
|
||||||
* ---
|
* ---
|
||||||
* Once you have configured the _lexer, call byToken$(LPAREN)$(RPAREN) on your
|
* Once you have configured the _lexer, call byToken$(LPAREN)$(RPAREN) on your
|
||||||
|
@ -200,7 +200,7 @@ enum IterationStyle
|
||||||
includeWhitespace = 0b0010,
|
includeWhitespace = 0b0010,
|
||||||
/// Include $(LINK2 http://dlang.org/lex.html#specialtokens, special tokens)
|
/// Include $(LINK2 http://dlang.org/lex.html#specialtokens, special tokens)
|
||||||
includeSpecialTokens = 0b0100,
|
includeSpecialTokens = 0b0100,
|
||||||
/// Do not stop iteration on reaching the ___EOF__ token
|
/// Do not stop iteration on reaching the $(D_KEYWORD ___EOF__) token
|
||||||
ignoreEOF = 0b1000,
|
ignoreEOF = 0b1000,
|
||||||
/// Include _everything
|
/// Include _everything
|
||||||
everything = includeComments | includeWhitespace | ignoreEOF
|
everything = includeComments | includeWhitespace | ignoreEOF
|
||||||
|
@ -215,8 +215,8 @@ enum TokenStyle : uint
|
||||||
/**
|
/**
|
||||||
* Escape sequences will be replaced with their equivalent characters,
|
* Escape sequences will be replaced with their equivalent characters,
|
||||||
* enclosing quote characters will not be included. Special tokens such as
|
* enclosing quote characters will not be included. Special tokens such as
|
||||||
* __VENDOR__ will be replaced with their equivalent strings. Useful for
|
* $(D_KEYWORD ___VENDOR__) will be replaced with their equivalent strings.
|
||||||
* creating a compiler or interpreter.
|
* Useful for creating a compiler or interpreter.
|
||||||
*/
|
*/
|
||||||
default_ = 0b0000,
|
default_ = 0b0000,
|
||||||
|
|
||||||
|
@ -236,8 +236,8 @@ enum TokenStyle : uint
|
||||||
includeQuotes = 0b0010,
|
includeQuotes = 0b0010,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not replace the value field of the special tokens such as ___DATE__
|
* Do not replace the value field of the special tokens such as
|
||||||
* with their string equivalents.
|
* $(D_KEYWORD ___DATE__) with their string equivalents.
|
||||||
*/
|
*/
|
||||||
doNotReplaceSpecial = 0b0100,
|
doNotReplaceSpecial = 0b0100,
|
||||||
|
|
||||||
|
@ -265,12 +265,12 @@ struct LexerConfig
|
||||||
TokenStyle tokenStyle = tokenStyle.default_;
|
TokenStyle tokenStyle = tokenStyle.default_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replacement for the ___VERSION__ token. Defaults to 100.
|
* Replacement for the $(D_KEYWORD ___VERSION__) token. Defaults to 100.
|
||||||
*/
|
*/
|
||||||
uint versionNumber = 100;
|
uint versionNumber = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replacement for the ___VENDOR__ token. Defaults to $(D_STRING "std.d.lexer")
|
* Replacement for the $(D_KEYWORD ___VENDOR__) token. Defaults to $(D_STRING "std.d.lexer")
|
||||||
*/
|
*/
|
||||||
string vendorString = "std.d.lexer";
|
string vendorString = "std.d.lexer";
|
||||||
|
|
||||||
|
@ -597,7 +597,7 @@ L_advance:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.iterStyle & TokenStyle.doNotReplaceSpecial)
|
if (config.tokenStyle & TokenStyle.doNotReplaceSpecial)
|
||||||
return;
|
return;
|
||||||
expandSpecialToken();
|
expandSpecialToken();
|
||||||
}
|
}
|
||||||
|
@ -2682,7 +2682,8 @@ immutable(string[TokenType.max + 1]) tokenValues = [
|
||||||
"__LINE__",
|
"__LINE__",
|
||||||
"__MODULE__",
|
"__MODULE__",
|
||||||
"__FUNCTION__",
|
"__FUNCTION__",
|
||||||
"__PRETTY_FUNCTION",
|
"__PRETTY_FUNCTION__",
|
||||||
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
@ -2704,7 +2705,6 @@ immutable(string[TokenType.max + 1]) tokenValues = [
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
pure string getTokenValue(const TokenType type)
|
pure string getTokenValue(const TokenType type)
|
||||||
|
@ -2867,6 +2867,7 @@ pure TokenType lookupTokenType(R)(R input)
|
||||||
case '_': if (input[1..$].equal("_DATE__")) return TokenType.specialDate;
|
case '_': if (input[1..$].equal("_DATE__")) return TokenType.specialDate;
|
||||||
else if (input[1..$].equal("_FILE__")) return TokenType.specialFile;
|
else if (input[1..$].equal("_FILE__")) return TokenType.specialFile;
|
||||||
else if (input[1..$].equal("_LINE__")) return TokenType.specialLine;
|
else if (input[1..$].equal("_LINE__")) return TokenType.specialLine;
|
||||||
|
else if (input[1..$].equal("_vector")) return TokenType.vector;
|
||||||
else if (input[1..$].equal("_TIME__")) return TokenType.specialTime;
|
else if (input[1..$].equal("_TIME__")) return TokenType.specialTime;
|
||||||
else if (input[1..$].equal("_traits")) return TokenType.traits; else break;
|
else if (input[1..$].equal("_traits")) return TokenType.traits; else break;
|
||||||
case 'a': if (input[1..$].equal("bstract")) return TokenType.abstract_; else break;
|
case 'a': if (input[1..$].equal("bstract")) return TokenType.abstract_; else break;
|
||||||
|
@ -2909,7 +2910,8 @@ pure TokenType lookupTokenType(R)(R input)
|
||||||
switch (input[0])
|
switch (input[0])
|
||||||
{
|
{
|
||||||
case 's': if (input[1..$].equal("ynchronized")) return TokenType.synchronized_; else break;
|
case 's': if (input[1..$].equal("ynchronized")) return TokenType.synchronized_; else break;
|
||||||
case '_': if (input[1..$].equal("_FUNCTION__")) return TokenType.specialFunction; else break;
|
case '_': if (input[1..$].equal("_FUNCTION__")) return TokenType.specialFunction;
|
||||||
|
else if (input[1..$].equal("_parameters")) return TokenType.parameters; else break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3306,7 +3308,8 @@ unittest
|
||||||
~ " interface invariant is lazy macro mixin module new nothrow null"
|
~ " interface invariant is lazy macro mixin module new nothrow null"
|
||||||
~ " out override pure ref return struct super switch template this"
|
~ " out override pure ref return struct super switch template this"
|
||||||
~ " throw true try typedef typeid typeof union unittest version volatile"
|
~ " throw true try typedef typeid typeof union unittest version volatile"
|
||||||
~ " while with __traits __parameters __vector");
|
~ " while with __traits __parameters __vector __VENDOR__ __MODULE__"
|
||||||
|
~ " __VERSION__ __TIMESTAMP__ __PRETTY_FUNCTION__");
|
||||||
auto expected = ["bool", "byte", "cdouble",
|
auto expected = ["bool", "byte", "cdouble",
|
||||||
"cent", "cfloat", "char", "creal",
|
"cent", "cfloat", "char", "creal",
|
||||||
"dchar", "double", "float", "function",
|
"dchar", "double", "float", "function",
|
||||||
|
@ -3329,8 +3332,11 @@ unittest
|
||||||
"super", "switch", "template", "this", "throw",
|
"super", "switch", "template", "this", "throw",
|
||||||
"true", "try", "typedef", "typeid", "typeof",
|
"true", "try", "typedef", "typeid", "typeof",
|
||||||
"union", "unittest", "version", "volatile",
|
"union", "unittest", "version", "volatile",
|
||||||
"while", "with", "__traits", "__parameters", "__vector"];
|
"while", "with", "__traits", "__parameters", "__vector",
|
||||||
|
"__VENDOR__", "__MODULE__", "__VERSION__", "__TIMESTAMP__",
|
||||||
|
"__PRETTY_FUNCTION__"];
|
||||||
LexerConfig config;
|
LexerConfig config;
|
||||||
|
config.tokenStyle = TokenStyle.doNotReplaceSpecial;
|
||||||
auto tokens = byToken(source, config);
|
auto tokens = byToken(source, config);
|
||||||
// writeln(tokens.map!"a.value"().array());
|
// writeln(tokens.map!"a.value"().array());
|
||||||
assert (equal(map!"a.value"(tokens), expected));
|
assert (equal(map!"a.value"(tokens), expected));
|
||||||
|
@ -3387,7 +3393,7 @@ unittest
|
||||||
assert (tokens.front.line == 1);
|
assert (tokens.front.line == 1);
|
||||||
assert (tokens.moveFront() == TokenType.int_);
|
assert (tokens.moveFront() == TokenType.int_);
|
||||||
assert (tokens.front.line == 4);
|
assert (tokens.front.line == 4);
|
||||||
assert (isType(tokens.front));
|
assert (isBasicType(tokens.front));
|
||||||
assert (tokens.front.value == "double");
|
assert (tokens.front.value == "double");
|
||||||
tokens.popFront();
|
tokens.popFront();
|
||||||
assert (tokens.front.value == "abcde (a + b) == 0", tokens.front.value);
|
assert (tokens.front.value == "abcde (a + b) == 0", tokens.front.value);
|
||||||
|
|
466
std/d/parser.d
466
std/d/parser.d
|
@ -13,7 +13,10 @@
|
||||||
* Authors: Brian Schott
|
* Authors: Brian Schott
|
||||||
* Source: $(PHOBOSSRC std/d/_parser.d)
|
* Source: $(PHOBOSSRC std/d/_parser.d)
|
||||||
* MACROS:
|
* MACROS:
|
||||||
* GRAMMAR = <pre>$0</pre>
|
* 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="font-style:italic; color: green; font-weight: normal;">$0</span>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module std.d.parser;
|
module std.d.parser;
|
||||||
|
@ -22,6 +25,7 @@ import std.d.lexer;
|
||||||
import std.d.ast;
|
import std.d.ast;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
|
import std.array;
|
||||||
version(unittest) import std.stdio;
|
version(unittest) import std.stdio;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,8 +47,10 @@ struct Parser
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Parses an AddExpression.
|
* Parses an AddExpression.
|
||||||
* $(GRAMMAR addExpression: mulExpression
|
*
|
||||||
* | addExpression ('+' | '-' | '~') mulExpression
|
* $(GRAMMAR $(RULEDEF addExpression):
|
||||||
|
* $(RULE mulExpression)
|
||||||
|
* | $(RULE addExpression) $(LPAREN)$(LITERAL '+') | $(LITERAL'-') | $(LITERAL'~')$(RPAREN) $(RULE mulExpression)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
AddExpression parseAddExpression()
|
AddExpression parseAddExpression()
|
||||||
|
@ -63,8 +69,10 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an AliasDeclaration
|
* Parses an AliasDeclaration.
|
||||||
* $(GRAMMAR aliasDeclaration: 'alias' (aliasInitializer (',' aliasInitializer)* | type declarator) ';'
|
*
|
||||||
|
* $(GRAMMAR $(RULEDEF aliasDeclaration):
|
||||||
|
* $(LITERAL 'alias') $(LPAREN)$(RULE aliasInitializer) $(LPAREN)$(LITERAL ',') $(RULE aliasInitializer)$(RPAREN)* | $(RULE type) $(RULE declarator)$(RPAREN) $(LITERAL ';')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
AliasDeclaration parseAliasDeclaration()
|
AliasDeclaration parseAliasDeclaration()
|
||||||
|
@ -80,7 +88,8 @@ struct Parser
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an AliasInitializer
|
* Parses an AliasInitializer
|
||||||
* $(GRAMMAR aliasInitializer: Identifier '=' type
|
* $(GRAMMAR $(RULEDEF aliasInitializer):
|
||||||
|
* $(LITERAL Identifier) $(LITERAL '=') $(RULE type)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
AliasInitializer parseAliasInitializer()
|
AliasInitializer parseAliasInitializer()
|
||||||
|
@ -94,7 +103,7 @@ struct Parser
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an AliasThisDeclaration
|
* Parses an AliasThisDeclaration
|
||||||
* $(GRAMMAR aliasThisDeclaration: 'alias' Identifier 'this' ';'
|
* $(GRAMMAR $(RULEDEF aliasThisDeclaration): $(LITERAL 'alias') $(LITERAL Identifier) $(LITERAL 'this') $(LITERAL ';')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
AliasThisDeclaration parseAliasThisDeclaration()
|
AliasThisDeclaration parseAliasThisDeclaration()
|
||||||
|
@ -109,7 +118,7 @@ struct Parser
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an AlignAttribute.
|
* Parses an AlignAttribute.
|
||||||
* $(GRAMMAR alignAttribute: 'align' ('(' IntegerLiteral ')')?
|
* $(GRAMMAR $(RULEDEF alignAttribute): $(LITERAL 'align') ($(LITERAL '$(LPAREN)') $(LITERAL IntegerLiteral) $(LITERAL '$(RPAREN)'))?
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
AlignAttribute parseAlignAttribute()
|
AlignAttribute parseAlignAttribute()
|
||||||
|
@ -127,8 +136,9 @@ struct Parser
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an AndAndExpression
|
* Parses an AndAndExpression
|
||||||
* $(GRAMMAR andAndExpression: orExpression
|
* $(GRAMMAR $(RULEDEF andAndExpression):
|
||||||
* | andAndExpression '&&' orExpression
|
* $(RULE orExpression)
|
||||||
|
* | $(RULE andAndExpression) $(LITERAL '&&') $(RULE orExpression)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
AndAndExpression parseAndAndExpression()
|
AndAndExpression parseAndAndExpression()
|
||||||
|
@ -171,9 +181,11 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an Arguments
|
* Parses Arguments
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(GRAMMAR $(RULEDEF arguments):
|
||||||
|
* $(LITERAL '$(LPAREN)') $(RULE argumentList)? $(LITERAL '$(RPAREN)')
|
||||||
|
* ;)
|
||||||
*/
|
*/
|
||||||
Arguments parseArguments()
|
Arguments parseArguments()
|
||||||
{
|
{
|
||||||
|
@ -199,7 +211,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an ArrayLiteral
|
* Parses an ArrayLiteral
|
||||||
*
|
*
|
||||||
* $(GRAMMAR arrayLiteral: '[' argumentList ']'
|
* $(GRAMMAR $(RULEDEF arrayLiteral):
|
||||||
|
* $(LITERAL '[') $(RULE argumentList) $(LITERAL ']')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
ArrayLiteral parseArrayLiteral()
|
ArrayLiteral parseArrayLiteral()
|
||||||
|
@ -490,7 +503,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an AssocArrayLiteral
|
* Parses an AssocArrayLiteral
|
||||||
*
|
*
|
||||||
* $(GRAMMAR assocArrayLiteral: '[' keyValuePairs ']'
|
* $(GRAMMAR $(RULEDEF assocArrayLiteral):
|
||||||
|
* $(LITERAL '[') $(RULE keyValuePairs) $(LITERAL ']')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
AssocArrayLiteral parseAssocArrayLiteral()
|
AssocArrayLiteral parseAssocArrayLiteral()
|
||||||
|
@ -529,12 +543,27 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an AttributedDeclaration
|
* Parses an AttributedDeclaration
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(GRAMMAR $(RULEDEF attributedDeclaration):
|
||||||
|
* $(RULE attribute) ($(LITERAL ':') | $(RULE declaration) | $(LITERAL '{') $(RULE declaration)* $(LITERAL '}'))
|
||||||
|
* ;)
|
||||||
*/
|
*/
|
||||||
AttributedDeclaration parseAttributedDeclaration()
|
AttributedDeclaration parseAttributedDeclaration()
|
||||||
{
|
{
|
||||||
auto node = new AttributedDeclaration;
|
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;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,7 +582,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a BlockStatement
|
* Parses a BlockStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR blockStatement: '{' declarationsAndStatements? '}'
|
* $(GRAMMAR $(RULEDEF blockStatement):
|
||||||
|
* $(LITERAL '{') $(RULE declarationsAndStatements)? $(LITERAL '}')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
BlockStatement parseBlockStatement()
|
BlockStatement parseBlockStatement()
|
||||||
|
@ -569,7 +599,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a BodyStatement
|
* Parses a BodyStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR bodyStatement: 'body' blockStatement
|
* $(GRAMMAR $(RULEDEF bodyStatement):
|
||||||
|
* $(LITERAL 'body') $(RULE blockStatement)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
BodyStatement parseBodyStatement()
|
BodyStatement parseBodyStatement()
|
||||||
|
@ -583,7 +614,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a BreakStatement
|
* Parses a BreakStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR breakStatement: 'break' Identifier? ';'
|
* $(GRAMMAR $(RULEDEF breakStatement):
|
||||||
|
* $(LITERAL 'break') $(LITERAL Identifier)? $(LITERAL ';')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
BreakStatement parseBreakStatement()
|
BreakStatement parseBreakStatement()
|
||||||
|
@ -609,28 +641,29 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an BuiltinType
|
* Parses an BuiltinType
|
||||||
*
|
*
|
||||||
* $(GRAMMAR builtinType: 'bool'
|
* $(GRAMMAR $(RULEDEF builtinType):
|
||||||
* | 'byte'
|
* $(LITERAL 'bool')
|
||||||
* | 'ubyte'
|
* | $(LITERAL 'byte')
|
||||||
* | 'short'
|
* | $(LITERAL 'ubyte')
|
||||||
* | 'ushort'
|
* | $(LITERAL 'short')
|
||||||
* | 'int'
|
* | $(LITERAL 'ushort')
|
||||||
* | 'uint'
|
* | $(LITERAL 'int')
|
||||||
* | 'long'
|
* | $(LITERAL 'uint')
|
||||||
* | 'ulong'
|
* | $(LITERAL 'long')
|
||||||
* | 'char'
|
* | $(LITERAL 'ulong')
|
||||||
* | 'wchar'
|
* | $(LITERAL 'char')
|
||||||
* | 'dchar'
|
* | $(LITERAL 'wchar')
|
||||||
* | 'float'
|
* | $(LITERAL 'dchar')
|
||||||
* | 'double'
|
* | $(LITERAL 'float')
|
||||||
* | 'real'
|
* | $(LITERAL 'double')
|
||||||
* | 'ifloat'
|
* | $(LITERAL 'real')
|
||||||
* | 'idouble'
|
* | $(LITERAL 'ifloat')
|
||||||
* | 'ireal'
|
* | $(LITERAL 'idouble')
|
||||||
* | 'cfloat'
|
* | $(LITERAL 'ireal')
|
||||||
* | 'cdouble'
|
* | $(LITERAL 'cfloat')
|
||||||
* | 'creal'
|
* | $(LITERAL 'cdouble')
|
||||||
* | 'void'
|
* | $(LITERAL 'creal')
|
||||||
|
* | $(LITERAL 'void')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
BasicType parseBasicType()
|
BasicType parseBasicType()
|
||||||
|
@ -649,7 +682,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a CaseRangeStatement
|
* Parses a CaseRangeStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR caseRangeStatement: 'case' assignExpression ':' '...' 'case' assignExpression ':' declarationsAndStatements
|
* $(GRAMMAR $(RULEDEF caseRangeStatement):
|
||||||
|
* $(LITERAL 'case') $(RULE assignExpression) $(LITERAL ':') $(LITERAL '...') $(LITERAL 'case') $(RULE assignExpression) $(LITERAL ':') $(RULE declarationsAndStatements)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
CaseRangeStatement parseCaseRangeStatement()
|
CaseRangeStatement parseCaseRangeStatement()
|
||||||
|
@ -669,7 +703,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an CaseStatement
|
* Parses an CaseStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR caseStatement: 'case' argumentList ':' declarationsAndStatements
|
* $(GRAMMAR $(RULEDEF caseStatement):
|
||||||
|
* $(LITERAL 'case') $(RULE argumentList) $(LITERAL ':') $(RULE declarationsAndStatements)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
CaseStatement parseCaseStatement()
|
CaseStatement parseCaseStatement()
|
||||||
|
@ -683,28 +718,55 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an CastExpression
|
* Parses a CastExpression
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(GRAMMAR $(RULEDEF castExpression):
|
||||||
|
* $(LITERAL 'cast') $(LITERAL '$(LPAREN)') ($(RULE type) | $(RULE castQualifier))? $(LITERAL '$(RPAREN)') $(RULE unaryExpression)
|
||||||
|
* ;)
|
||||||
*/
|
*/
|
||||||
CastExpression parseCastExpression()
|
CastExpression parseCastExpression()
|
||||||
{
|
{
|
||||||
auto node = new CastExpression;
|
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;
|
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
|
* Parses a CastQualifier
|
||||||
*
|
*
|
||||||
* $(GRAMMAR castQualifier: 'const'
|
* $(GRAMMAR $(RULEDEF castQualifier):
|
||||||
* | 'const' 'shared'
|
* $(LITERAL 'const')
|
||||||
* | 'immutable'
|
* | $(LITERAL 'const') $(LITERAL 'shared')
|
||||||
* | 'inout'
|
* | $(LITERAL 'immutable')
|
||||||
* | 'inout' 'shared'
|
* | $(LITERAL 'inout')
|
||||||
* | 'shared'
|
* | $(LITERAL 'inout') $(LITERAL 'shared')
|
||||||
* | 'shared' 'const'
|
* | $(LITERAL 'shared')
|
||||||
* | 'shared' 'inout'
|
* | $(LITERAL 'shared') $(LITERAL 'const')
|
||||||
|
* | $(LITERAL 'shared') $(LITERAL 'inout')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
CastQualifier parseCastQualifier()
|
CastQualifier parseCastQualifier()
|
||||||
|
@ -736,7 +798,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a Catch
|
* Parses a Catch
|
||||||
*
|
*
|
||||||
* $(GRAMMAR catch_: 'catch' '(' type Identifier? ')' nonEmptyStatementNoCaseNoDefault
|
* $(GRAMMAR $(RULEDEF catch):
|
||||||
|
* $(LITERAL 'catch') $(LITERAL '$(LPAREN)') $(RULE type) $(LITERAL Identifier)? $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Catch parseCatch()
|
Catch parseCatch()
|
||||||
|
@ -767,7 +830,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an ClassBody
|
* Parses an ClassBody
|
||||||
*
|
*
|
||||||
* $(GRAMMAR classBody: '{' declarationOrInvariant* '}'
|
* $(GRAMMAR $(RULEDEF classBody):
|
||||||
|
* $(LITERAL '{') $(RULE declarationOrInvariant)* $(LITERAL '}')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
ClassBody parseClassBody()
|
ClassBody parseClassBody()
|
||||||
|
@ -783,7 +847,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an ClassDeclaration
|
* Parses an ClassDeclaration
|
||||||
*
|
*
|
||||||
* $(GRAMMAR classDeclaration: 'class' Identifier (templateParameters constraint?)? (':' identifierList )? classBody
|
* $(GRAMMAR $(RULEDEF classDeclaration):
|
||||||
|
* $(LITERAL 'class') $(LITERAL Identifier) ($(RULE templateParameters) $(RULE constraint)?)? ($(LITERAL ':') $(RULE identifierList))? $(RULE classBody)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
ClassDeclaration parseClassDeclaration()
|
ClassDeclaration parseClassDeclaration()
|
||||||
|
@ -818,9 +883,10 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a CompileCondition
|
* Parses a CompileCondition
|
||||||
*
|
*
|
||||||
* $(GRAMMAR compileCondition: versionCondition
|
* $(GRAMMAR $(RULEDEF compileCondition):
|
||||||
* | debugCondition
|
* $(RULE versionCondition)
|
||||||
* | staticIfCondition
|
* | $(RULE debugCondition)
|
||||||
|
* | $(RULE staticIfCondition)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
CompileCondition parseCompileCondition()
|
CompileCondition parseCompileCondition()
|
||||||
|
@ -871,7 +937,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an Constraint
|
* Parses an Constraint
|
||||||
*
|
*
|
||||||
* $(GRAMMAR constraint: 'if' '(' expression ')'
|
* $(GRAMMAR $(RULEDEF constraint):
|
||||||
|
* $(LITERAL 'if') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Constraint parseConstraint()
|
Constraint parseConstraint()
|
||||||
|
@ -887,7 +954,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a Constructor
|
* Parses a Constructor
|
||||||
*
|
*
|
||||||
* $(GRAMMAR constructor: 'this' parameters functionBody
|
* $(GRAMMAR $(RULEDEF constructor):
|
||||||
|
* $(LITERAL 'this') $(RULE parameters) $(RULE functionBody)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Constructor parseConstructor()
|
Constructor parseConstructor()
|
||||||
|
@ -902,7 +970,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an ContinueStatement
|
* Parses an ContinueStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR continueStatement: 'continue' Identifier? ';'
|
* $(GRAMMAR $(RULEDEF continueStatement):
|
||||||
|
* $(LITERAL 'continue') $(LITERAL Identifier)? $(LITERAL ';')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
ContinueStatement parseContinueStatement()
|
ContinueStatement parseContinueStatement()
|
||||||
|
@ -926,9 +995,10 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an DebugCondition
|
* Parses a DebugCondition
|
||||||
*
|
*
|
||||||
* $(GRAMMAR debugCondition: 'debug' ('(' (IntegerLiteral | Identifier) ')')?
|
* $(GRAMMAR $(RULEDEF debugCondition):
|
||||||
|
* $(LITERAL 'debug') ($(LITERAL '$(LPAREN)') ($(LITERAL IntegerLiteral) | $(LITERAL Identifier)) $(LITERAL '$(RPAREN)'))?
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
DebugCondition parseDebugCondition()
|
DebugCondition parseDebugCondition()
|
||||||
|
@ -956,7 +1026,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a DebugSpecification
|
* Parses a DebugSpecification
|
||||||
*
|
*
|
||||||
* $(GRAMMAR debugSpecification: 'debug' '=' (Identifier | IntegerLiteral) ';'
|
* $(GRAMMAR $(RULEDEF debugSpecification):
|
||||||
|
* $(LITERAL 'debug') $(LITERAL '=') ($(LITERAL Identifier) | $(LITERAL IntegerLiteral)) $(LITERAL ';')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
DebugSpecification parseDebugSpecification()
|
DebugSpecification parseDebugSpecification()
|
||||||
|
@ -978,29 +1049,30 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a Declaration
|
* Parses a Declaration
|
||||||
*
|
*
|
||||||
* $(GRAMMAR declaration: aliasDeclaration
|
* $(GRAMMAR $(RULEDEF declaration):
|
||||||
* | aliasThisDeclaration
|
* $(RULE aliasDeclaration)
|
||||||
* | attributedDeclaration
|
* | $(RULE aliasThisDeclaration)
|
||||||
* | classDeclaration
|
* | $(RULE attributedDeclaration)
|
||||||
* | conditionalDeclaration
|
* | $(RULE classDeclaration)
|
||||||
* | constructor
|
* | $(RULE conditionalDeclaration)
|
||||||
* | destructor
|
* | $(RULE constructor)
|
||||||
* | enumDeclaration
|
* | $(RULE destructor)
|
||||||
* | functionDeclaration
|
* | $(RULE enumDeclaration)
|
||||||
* | importDeclaration
|
* | $(RULE functionDeclaration)
|
||||||
* | interfaceDeclaration
|
* | $(RULE importDeclaration)
|
||||||
* | mixinDeclaration
|
* | $(RULE interfaceDeclaration)
|
||||||
* | pragmaDeclaration
|
* | $(RULE mixinDeclaration)
|
||||||
* | sharedStaticConstructor
|
* | $(RULE pragmaDeclaration)
|
||||||
* | sharedStaticDestructor
|
* | $(RULE sharedStaticConstructor)
|
||||||
* | staticAssertDeclaration
|
* | $(RULE sharedStaticDestructor)
|
||||||
* | staticConstructor
|
* | $(RULE staticAssertDeclaration)
|
||||||
* | staticDestructor
|
* | $(RULE staticConstructor)
|
||||||
* | structDeclaration
|
* | $(RULE staticDestructor)
|
||||||
* | templateDeclaration
|
* | $(RULE structDeclaration)
|
||||||
* | unionDeclaration
|
* | $(RULE templateDeclaration)
|
||||||
* | unittest
|
* | $(RULE unionDeclaration)
|
||||||
* | variableDeclaration
|
* | $(RULE unittest)
|
||||||
|
* | $(RULE variableDeclaration)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Declaration parseDeclaration()
|
Declaration parseDeclaration()
|
||||||
|
@ -1094,8 +1166,9 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a DeclarationOrInvariant
|
* Parses a DeclarationOrInvariant
|
||||||
*
|
*
|
||||||
* $(GRAMMAR declarationOrInvariant : declaration
|
* $(GRAMMAR $(RULEDEF declarationOrInvariant):
|
||||||
* | invariant
|
* $(RULE declaration)
|
||||||
|
* | $(RULE invariant)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
DeclarationOrInvariant parseDeclarationOrInvariant()
|
DeclarationOrInvariant parseDeclarationOrInvariant()
|
||||||
|
@ -1111,7 +1184,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a Declarator
|
* Parses a Declarator
|
||||||
*
|
*
|
||||||
* $(GRAMMAR declarator: Identifier declaratorSuffix? ('=' initializer)?
|
* $(GRAMMAR $(RULEDEF declarator):
|
||||||
|
* $(LITERAL Identifier) $(RULE declaratorSuffix)? ($(LITERAL '=') $(RULE initializer))?
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Declarator parseDeclarator()
|
Declarator parseDeclarator()
|
||||||
|
@ -1179,7 +1253,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a Deprecated attribute
|
* Parses a Deprecated attribute
|
||||||
*
|
*
|
||||||
* $(GRAMMAR deprecated: 'deprecated' ('(' assignExpression ')')?
|
* $(GRAMMAR $(RULEDEF deprecated):
|
||||||
|
* $(LITERAL 'deprecated') ($(LITERAL '$(LPAREN)') $(RULE assignExpression) $(LITERAL '$(RPAREN)'))?
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Deprecated parseDeprecated()
|
Deprecated parseDeprecated()
|
||||||
|
@ -1198,7 +1273,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a Destructor
|
* Parses a Destructor
|
||||||
*
|
*
|
||||||
* $(GRAMMAR destructor: '~' 'this' '(' ')' functionBody
|
* $(GRAMMAR $(RULEDEF destructor):
|
||||||
|
* $(LITERAL '~') $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') $(RULE functionBody)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Destructor parseDestructor()
|
Destructor parseDestructor()
|
||||||
|
@ -1213,50 +1289,93 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an DoStatement
|
* Parses a DoStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(GRAMMAR $(RULEDEF doStatement):
|
||||||
|
* $(LITERAL 'do') $(RULE blockStatement) $(LITERAL 'while') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)') $(LITERAL ';')
|
||||||
|
* ;)
|
||||||
*/
|
*/
|
||||||
DoStatement parseDoStatement()
|
DoStatement parseDoStatement()
|
||||||
{
|
{
|
||||||
auto node = new DoStatement;
|
auto node = new DoStatement;
|
||||||
|
expect(TokenType.do_);
|
||||||
|
node.blockStatement = parseBlockStatement();
|
||||||
|
expect(TokenType.while_);
|
||||||
|
expect(TokenType.lParen);
|
||||||
|
node.expression = parseExpression();
|
||||||
|
expect(TokenType.rParen);
|
||||||
|
expect(TokenType.semicolon);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an EnumBody
|
* Parses an EnumBody
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(GRAMMAR $(RULEDEF enumBody):
|
||||||
|
* $(LITERAL ';')
|
||||||
|
* | $(LITERAL '{') $(RULE enumMember) ($(LITERAL ',') $(RULE enumMember)?)* $(LITERAL '}')
|
||||||
|
* ;)
|
||||||
*/
|
*/
|
||||||
EnumBody parseEnumBody()
|
EnumBody parseEnumBody()
|
||||||
{
|
{
|
||||||
auto node = new EnumBody;
|
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;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an EnumDeclaration
|
* Parses an EnumDeclaration
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(GRAMMAR $(RULEDEF enumDeclaration):
|
||||||
|
* $(LITERAL 'enum') $(LITERAL Identifier)? ($(LITERAL ':') $(RULE type))? $(RULE enumBody)
|
||||||
|
* ;)
|
||||||
*/
|
*/
|
||||||
EnumDeclaration parseEnumDeclaration()
|
EnumDeclaration parseEnumDeclaration()
|
||||||
{
|
{
|
||||||
auto node = new EnumDeclaration;
|
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;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an EnumMember
|
* Parses an EnumMember
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(GRAMMAR $(RULEDEF enumMember):
|
||||||
|
* $(LITERAL Identifier)
|
||||||
|
* | ($(LITERAL Identifier) | $(RULE type)) $(LITERAL '=') $(RULE assignExpression)
|
||||||
|
* ;)
|
||||||
*/
|
*/
|
||||||
EnumMember parseEnumMember()
|
EnumMember parseEnumMember()
|
||||||
{
|
{
|
||||||
auto node = new EnumMember;
|
auto node = new EnumMember;
|
||||||
|
// TODO
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1454,7 +1573,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an IdentifierChain
|
* Parses an IdentifierChain
|
||||||
*
|
*
|
||||||
* $(GRAMMAR identifierChain: Identifier ('.' Identifier)*
|
* $(GRAMMAR $(RULEDEF identifierChain):
|
||||||
|
* $(LITERAL Identifier) ($(LITERAL '.') $(LITERAL Identifier))*
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
IdentifierChain parseIdentifierChain()
|
IdentifierChain parseIdentifierChain()
|
||||||
|
@ -1474,10 +1594,23 @@ struct Parser
|
||||||
return node;
|
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
|
* Parses an IdentifierList
|
||||||
*
|
*
|
||||||
* $(GRAMMAR identifierList: Identifier (',' Identifier)*
|
* $(GRAMMAR $(RULEDEF identifierList):
|
||||||
|
* $(LITERAL Identifier) ($(LITERAL ',') $(LITERAL Identifier))*
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
IdentifierList parseIdentifierList()
|
IdentifierList parseIdentifierList()
|
||||||
|
@ -1605,6 +1738,20 @@ struct Parser
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an IndexExpression
|
||||||
|
*
|
||||||
|
* $(GRAMMAR $(RULEDEF indexExpression):
|
||||||
|
* $(RULE unaryExpression) $(LITERAL '[') $(RULE argumentList) $(LITERAL ']')
|
||||||
|
* ;)
|
||||||
|
*/
|
||||||
|
IndexExpression parseImportList()
|
||||||
|
{
|
||||||
|
auto node = new IndexExpression;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an InExpression
|
* Parses an InExpression
|
||||||
*
|
*
|
||||||
|
@ -1753,7 +1900,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an LinkageAttribute
|
* Parses an LinkageAttribute
|
||||||
*
|
*
|
||||||
* $(GRAMMAR linkageAttribute: 'extern' '(' Identifier '++'? ')'
|
* $(GRAMMAR $(RULEDEF linkageAttribute):
|
||||||
|
* $(LITERAL 'extern') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) $(LITERAL '++')? $(LITERAL '$(RPAREN)')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
LinkageAttribute parseLinkageAttribute()
|
LinkageAttribute parseLinkageAttribute()
|
||||||
|
@ -1786,7 +1934,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses an MixinDeclaration
|
* Parses an MixinDeclaration
|
||||||
*
|
*
|
||||||
* $(GRAMMAR mixinDeclaration: mixinExpression ';'
|
* $(GRAMMAR $(RULEDEF mixinDeclaration):
|
||||||
|
* $(RULE mixinExpression) $(LITERAL ';')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
MixinDeclaration parseMixinDeclaration()
|
MixinDeclaration parseMixinDeclaration()
|
||||||
|
@ -1824,7 +1973,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a Module
|
* Parses a Module
|
||||||
*
|
*
|
||||||
* $(GRAMMAR module: moduleDeclaration? declaration*
|
* $(GRAMMAR $(RULEDEF module):
|
||||||
|
* $(RULE moduleDeclaration)? $(RULE declaration)*
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Module parseModule()
|
Module parseModule()
|
||||||
|
@ -1850,7 +2000,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a ModuleDeclaration
|
* Parses a ModuleDeclaration
|
||||||
*
|
*
|
||||||
* $(GRAMMAR moduleDeclaration: 'module' identifierChain ';'
|
* $(GRAMMAR $(RULEDEF moduleDeclaration):
|
||||||
|
* $(LITERAL 'module') $(RULE identifierChain) $(LITERAL ';')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
ModuleDeclaration parseModuleDeclaration()
|
ModuleDeclaration parseModuleDeclaration()
|
||||||
|
@ -1864,8 +2015,9 @@ struct Parser
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a MulExpression
|
* Parses a MulExpression
|
||||||
* $(GRAMMAR mulExpression: unaryExpression
|
* $(GRAMMAR $(RULEDEF mulExpression):
|
||||||
* | mulExpression ('*' | '/' | '%') unaryExpression
|
* $(RULE unaryExpression)
|
||||||
|
* | $(RULE mulExpression) ($(LITERAL '*') | $(LITERAL '/') | $(LITERAL '%')) $(RULE unaryExpression)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
MulExpression parseMulExpression()
|
MulExpression parseMulExpression()
|
||||||
|
@ -2233,8 +2385,9 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a Statement
|
* Parses a Statement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR statement: ';'
|
* $(GRAMMAR $(RULEDEF statement):
|
||||||
* | nonEmptyStatement
|
* $(LITERAL ';')
|
||||||
|
* | $(RULE nonEmptyStatement)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Statement parseStatement()
|
Statement parseStatement()
|
||||||
|
@ -2364,9 +2517,10 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an StructDeclaration
|
* Parses a StructDeclaration
|
||||||
*
|
*
|
||||||
* $(GRAMMAR structDeclaration: 'struct' Identifier (templateParameters constraint? structBody | (structBody | ';'))
|
* $(GRAMMAR $(RULEDEF structDeclaration):
|
||||||
|
* $(LITERAL 'struct') $(LITERAL Identifier) ($(RULE templateParameters) $(RULE constraint)? $(RULE structBody) | ($(RULE structBody) | $(LITERAL ';')))
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
StructDeclaration parseStructDeclaration()
|
StructDeclaration parseStructDeclaration()
|
||||||
|
@ -2881,9 +3035,27 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an UnaryExpression
|
* Parses a UnaryExpression
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(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()
|
UnaryExpression parseUnaryExpression()
|
||||||
{
|
{
|
||||||
|
@ -2905,9 +3077,11 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an Unittest
|
* Parses a Unittest
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(GRAMMAR $(RULEDEF unittest):
|
||||||
|
* $(LITERAL 'unittest') $(RULE blockStatement)
|
||||||
|
* ;)
|
||||||
*/
|
*/
|
||||||
Unittest parseUnittest()
|
Unittest parseUnittest()
|
||||||
{
|
{
|
||||||
|
@ -2932,7 +3106,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a VersionCondition
|
* Parses a VersionCondition
|
||||||
*
|
*
|
||||||
* $(GRAMMAR versionCondition: 'version' '(' (IntegerLiteral | Identifier | 'unittest' | 'assert') ')'
|
* $(GRAMMAR $(RULEDEF versionCondition):
|
||||||
|
* $(LITERAL 'version') $(LITERAL '$(LPAREN)') ($(LITERAL IntegerLiteral) | $(LITERAL Identifier) | $(LITERAL 'unittest') | $(LITERAL 'assert')) $(LITERAL '$(RPAREN)')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
VersionCondition parseVersionCondition()
|
VersionCondition parseVersionCondition()
|
||||||
|
@ -2957,7 +3132,8 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Parses a VersionSpecification
|
* Parses a VersionSpecification
|
||||||
*
|
*
|
||||||
* $(GRAMMAR versionSpecification: 'version' '=' (Identifier | IntegerLiteral) ';'
|
* $(GRAMMAR $(RULEDEF versionSpecification):
|
||||||
|
* $(LITERAL 'version') $(LITERAL '=') ($(LITERAL Identifier) | $(LITERAL IntegerLiteral)) $(LITERAL ';')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
VersionSpecification parseVersionSpecification()
|
VersionSpecification parseVersionSpecification()
|
||||||
|
@ -2976,9 +3152,10 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an WhileStatement
|
* Parses a WhileStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR whileStatement: 'while' '(' expression ')' statementNoCaseNoDefault
|
* $(GRAMMAR $(RULEDEF whileStatement):
|
||||||
|
* $(LITERAL 'while') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE statementNoCaseNoDefault)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
WhileStatement parseWhileStatement()
|
WhileStatement parseWhileStatement()
|
||||||
|
@ -2993,16 +3170,18 @@ struct Parser
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an WithStatement
|
* Parses a WithStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR )
|
* $(GRAMMAR $(RULEDEF withStatement):
|
||||||
|
* $(LITERAL 'with') $(LITERAL '$(LPAREN)') ($(RULE expression) | $(RULE symbol) | $(RULE templateInstance)) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
|
||||||
|
* ;)
|
||||||
*/
|
*/
|
||||||
WithStatement parseWithStatement()
|
WithStatement parseWithStatement()
|
||||||
{
|
{
|
||||||
auto node = new WithStatement;
|
auto node = new WithStatement;
|
||||||
expect(TokenType.with_);
|
expect(TokenType.with_);
|
||||||
expect(TokenType.lParen);
|
expect(TokenType.lParen);
|
||||||
// magic here
|
// TODO: magic here
|
||||||
expect(TokenType.rParen);
|
expect(TokenType.rParen);
|
||||||
parseNonEmptyStatementNoCaseNoDefault();
|
parseNonEmptyStatementNoCaseNoDefault();
|
||||||
return node;
|
return node;
|
||||||
|
@ -3033,7 +3212,7 @@ struct Parser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* peekPast(alias O, alias C)()
|
const(Token)* peekPast(alias O, alias C)()
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert (tokens[index].type == O);
|
assert (tokens[index].type == O);
|
||||||
|
@ -3059,26 +3238,37 @@ struct Parser
|
||||||
return depth == 0 ? &tokens[i] : null;
|
return depth == 0 ? &tokens[i] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* peekPastParens()
|
const(Token)* peekPastParens()
|
||||||
{
|
{
|
||||||
return peekPast!(TokenType.lParen, TokenType.rParen)();
|
return peekPast!(TokenType.lParen, TokenType.rParen)();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* peekPastBrackets()
|
const(Token)* peekPastBrackets()
|
||||||
{
|
{
|
||||||
return peekPast!(TokenType.lBracket, TokenType.rBracket)();
|
return peekPast!(TokenType.lBracket, TokenType.rBracket)();
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* peekPastBraces()
|
const(Token)* peekPastBraces()
|
||||||
{
|
{
|
||||||
return peekPast!(TokenType.lBrace, TokenType.rBrace)();
|
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
|
* Returns a token of the specified type if it was the next token, otherwise
|
||||||
* calls the error function and returns null.
|
* calls the error function and returns null.
|
||||||
*/
|
*/
|
||||||
Token* expect(TokenType type)
|
const(Token)* expect(TokenType type)
|
||||||
{
|
{
|
||||||
if (tokens[index].type == type)
|
if (tokens[index].type == type)
|
||||||
return &tokens[index++];
|
return &tokens[index++];
|
||||||
|
@ -3092,7 +3282,7 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Returns: the current token
|
* Returns: the current token
|
||||||
*/
|
*/
|
||||||
Token current()
|
Token current() const
|
||||||
{
|
{
|
||||||
return tokens[index];
|
return tokens[index];
|
||||||
}
|
}
|
||||||
|
@ -3108,20 +3298,20 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Returns: true if the current token has the given type
|
* Returns: true if the current token has the given type
|
||||||
*/
|
*/
|
||||||
bool currentIs(TokenType type)
|
bool currentIs(TokenType type) const
|
||||||
{
|
{
|
||||||
return tokens[index] == type;
|
return index < tokens.length && tokens[index] == type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns: true if the current token is one of the given types
|
* Returns: true if the current token is one of the given types
|
||||||
*/
|
*/
|
||||||
bool currentIsOneOf(TokenType[] types...)
|
bool currentIsOneOf(TokenType[] types...) const
|
||||||
{
|
{
|
||||||
return canFind(types, current().type);
|
return canFind(types, current().type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool startsWith(TokenType[] types...)
|
bool startsWith(TokenType[] types...) const
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i != types.length; ++i)
|
for (size_t i = 0; i != types.length; ++i)
|
||||||
{
|
{
|
||||||
|
@ -3134,13 +3324,13 @@ struct Parser
|
||||||
/**
|
/**
|
||||||
* Returns: true if there are more tokens
|
* Returns: true if there are more tokens
|
||||||
*/
|
*/
|
||||||
bool moreTokens()
|
bool moreTokens() const
|
||||||
{
|
{
|
||||||
return index < tokens.length;
|
return index < tokens.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint errorCount;
|
uint errorCount;
|
||||||
Token[] tokens;
|
const(Token)[] tokens;
|
||||||
size_t index;
|
size_t index;
|
||||||
string fileName;
|
string fileName;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue