diff --git a/std/d/parser.d b/std/d/parser.d index 7a99b33..dd8ef9a 100755 --- a/std/d/parser.d +++ b/std/d/parser.d @@ -90,8 +90,8 @@ Module parseModule(const(Token)[] tokens, string fileName) parser.fileName = fileName; parser.tokens = tokens; auto mod = parser.parseModule(); - writefln("Parsing finished with %d errors and %d warnings.", - parser.errorCount, parser.warningCount); + // writefln("Parsing finished with %d errors and %d warnings.", + // parser.errorCount, parser.warningCount); return mod; } @@ -1654,14 +1654,14 @@ class ClassFour(A, B) if (someTest()) : Super {}}c; node.classDeclaration = parseClassDeclaration(); break; case this_: - if (startsWith(this_, lParen, this_)) + if (startsWith(this_, lParen, this_)) { - node.postblit = parsePostblit(); + node.postblit = parsePostblit(); if (node.postblit is null) return null; } - else + else { - node.constructor = parseConstructor(); + node.constructor = parseConstructor(); if (node.constructor is null) return null; } break; @@ -1719,9 +1719,9 @@ class ClassFour(A, B) if (someTest()) : Super {}}c; case union_: node.unionDeclaration = parseUnionDeclaration(); break; - case invariant_: - node.invariant_ = parseInvariant(); - break; + case invariant_: + node.invariant_ = parseInvariant(); + break; case unittest_: node.unittest_ = parseUnittest(); break; @@ -1733,8 +1733,8 @@ class ClassFour(A, B) if (someTest()) : Super {}}c; node.variableDeclaration = parseVariableDeclaration(null, true); else if (peekIs(lParen)) node.functionDeclaration = parseFunctionDeclaration(null, true); - else - goto type; + else + goto type; } else goto type; @@ -1774,7 +1774,8 @@ class ClassFour(A, B) if (someTest()) : Super {}}c; break; default: error("Declaration expected"); - advance(); + if (moreTokens()) + advance(); return null; } return node; @@ -1785,7 +1786,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c; * * $(GRAMMAR $(RULEDEF declarationsAndStatements): * $(RULE declarationOrStatement)+ - * ; + * ;) */ DeclarationsAndStatements parseDeclarationsAndStatements() { @@ -3176,7 +3177,10 @@ invariant() foo(); * Parses a LambdaExpression * * $(GRAMMAR $(RULEDEF lambdaExpression): - * ($(LITERAL Identifier) | $(RULE parameters) $(RULE functionAttribute)* ) $(LITERAL '=>') $(RULE assignExpression) + * $(LITERAL Identifier) $(LITERAL '=>') $(RULE assignExpression) + * | $(LITERAL 'function') $(RULE parameters) $(RULE functionAttribute)* $(LITERAL '=>') $(RULE assignExpression) + * | $(LITERAL 'delegate') $(RULE parameters) $(RULE functionAttribute)* $(LITERAL '=>') $(RULE assignExpression) + * | $(RULE parameters) $(RULE functionAttribute)* $(LITERAL '=>') $(RULE assignExpression) * ;) */ LambdaExpression parseLambdaExpression() @@ -3301,8 +3305,13 @@ invariant() foo(); auto node = new MixinDeclaration; if (peekIs(TokenType.identifier)) node.templateMixinExpression = parseTemplateMixinExpression(); - else + else if (peekIs(TokenType.lParen)) node.mixinExpression = parseMixinExpression(); + else + { + error(`"(" or identifier expected`); + return null; + } expect(TokenType.semicolon); return node; } @@ -3735,11 +3744,11 @@ invariant() foo(); node.vararg = true; advance(); } - else if (currentIs(TokenType.assign)) - { - advance(); - node.default_ = parseAssignExpression(); - } + else if (currentIs(TokenType.assign)) + { + advance(); + node.default_ = parseAssignExpression(); + } return node; } @@ -3759,7 +3768,7 @@ invariant() foo(); */ TokenType parseParameterAttribute(bool validate = false) { - mixin(traceEnterAndExit!(__FUNCTION__)); + mixin(traceEnterAndExit!(__FUNCTION__)); with (TokenType) switch (current.type) { case immutable_: @@ -4034,6 +4043,20 @@ q{(int a, ...) break; case function_: case delegate_: + if (peekIs(lParen)) + { + auto b = setBookmark(); + advance(); // function | delegate + skipParens(); + if (currentIs(goesTo)) + { + goToBookmark(b); + goto lambda; + } + else + goToBookmark(b); + } + goto case; case lBrace: case in_: case out_: @@ -4063,6 +4086,7 @@ q{(int a, ...) if (currentIs(goesTo)) { goToBookmark(b); + lambda: node.lambdaExpression = parseLambdaExpression(); } else if (currentIs(lBrace)) @@ -4533,10 +4557,10 @@ q{(int a, ...) mixin(traceEnterAndExit!(__FUNCTION__)); auto node = new StructDeclaration; expect(TokenType.struct_); - if (currentIs(TokenType.identifier)) - { - node.name = advance(); - } + if (currentIs(TokenType.identifier)) + { + node.name = advance(); + } if (currentIs(TokenType.lParen)) { @@ -4802,8 +4826,8 @@ q{(int a, ...) if (currentIs(TokenType.lParen)) { advance(); - if (!currentIs(TokenType.rParen)) - node.templateArgumentList = parseTemplateArgumentList(); + if (!currentIs(TokenType.rParen)) + node.templateArgumentList = parseTemplateArgumentList(); expect(TokenType.rParen); } else @@ -4830,13 +4854,13 @@ q{(int a, ...) if (currentIs(TokenType.if_)) node.constraint = parseConstraint(); if (expect(TokenType.lBrace) is null) return null; - while (moreTokens() && !currentIs(TokenType.rBrace)) - { - auto decl = parseDeclaration(); - if (decl !is null) - node.declarations ~= decl; - } - expect(TokenType.rBrace); + while (moreTokens() && !currentIs(TokenType.rBrace)) + { + auto decl = parseDeclaration(); + if (decl !is null) + node.declarations ~= decl; + } + expect(TokenType.rBrace); return node; } @@ -5449,12 +5473,12 @@ q{(int a, ...) goToBookmark(bookmark); node.low = parseAssignExpression(); if (node.low is null) return null; - if (currentIs(slice)) - { - advance(); - node.high = parseAssignExpression(); - if (node.high is null) return null; - } + if (currentIs(slice)) + { + advance(); + node.high = parseAssignExpression(); + if (node.high is null) return null; + } } end: if (expect(TokenType.rBracket) is null) return null; @@ -6140,7 +6164,7 @@ private: auto column = index < tokens.length ? tokens[index].column : 0; auto line = index < tokens.length ? tokens[index].line : 0; if (messageFunction is null) - writefln("^^ %s(%d:%d): %s", fileName, line, column, message); + writefln("%s(%d:%d)[warn]: %s", fileName, line, column, message); else messageFunction(fileName, line, column, message); } @@ -6155,7 +6179,7 @@ private: column++; auto line = index < tokens.length ? tokens[index].line : 0; if (messageFunction is null) - stderr.writefln("!! %s(%d:%d): %s", fileName, line, column, message); + writefln("%s(%d:%d)[error]: %s", fileName, line, column, message); else messageFunction(fileName, line, column, message); } @@ -6275,7 +6299,7 @@ private: * 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, string loc = __PRETTY_FUNCTION__) + const(Token)* expect(TokenType type) { if (index < tokens.length && tokens[index].type == type) return &tokens[index++]; @@ -6283,10 +6307,10 @@ private: { if (tokenValues[type] is null) error("Expected " ~ to!string(type) ~ " instead of " - ~ (index < tokens.length ? tokens[index].value : "EOF") ~ " at " ~ loc); + ~ (index < tokens.length ? tokens[index].value : "EOF")); else error("Expected " ~ tokenValues[type] ~ " instead of " - ~ (index < tokens.length ? tokens[index].value : "EOF") ~ " at " ~ loc); + ~ (index < tokens.length ? tokens[index].value : "EOF")); return null; } }