Mercurial > projects > dil
diff trunk/src/dil/Parser.d @ 496:5a607597dc22
Improved error recovery in the Parser.
The Parser skips to the next valid token if an illegal Declaration, Statement
or AsmInstruction was found.
Refactored a few things in Lexer.d and LexerFuncs.d.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sun, 09 Dec 2007 13:04:15 +0100 |
parents | b60450804b6e |
children | 949a53332c66 |
line wrap: on
line diff
--- a/trunk/src/dil/Parser.d Sat Dec 08 22:20:34 2007 +0100 +++ b/trunk/src/dil/Parser.d Sun Dec 09 13:04:15 2007 +0100 @@ -345,9 +345,9 @@ // Declaration case T.Identifier, T.Dot, T.Typeof: // IntegralType - case T.Char, T.Wchar, T.Dchar, T.Bool, - T.Byte, T.Ubyte, T.Short, T.Ushort, - T.Int, T.Uint, T.Long, T.Ulong, + case T.Char, T.Wchar, T.Dchar, T.Bool, + T.Byte, T.Ubyte, T.Short, T.Ushort, + T.Int, T.Uint, T.Long, T.Ulong, T.Float, T.Double, T.Real, T.Ifloat, T.Idouble, T.Ireal, T.Cfloat, T.Cdouble, T.Creal, T.Void: @@ -357,9 +357,15 @@ // TODO: Error: module is optional and can appear only once at the top of the source file. break;+/ default: - error(MID.ExpectedButFound, "Declaration", token.srcText); - decl = new IllegalDeclaration(token); - nT(); + decl = new IllegalDeclaration(); + // Skip to next valid token. + do + nT(); + while (!token.isDeclDefStart && + token.type != T.RBrace && + token.type != T.EOF) + auto text = Token.textSpan(begin, this.prevToken); + error(begin, "illegal Declaration found: " ~ text); } decl.setProtection(this.protection); decl.setStorageClass(this.storageClass); @@ -702,19 +708,18 @@ break; default: error(MID.UnrecognizedLinkageType, token.srcText); - nT(); } require(T.RParen); return linkageType; } - void checkLinkageType(ref LinkageType prev_lt, LinkageType lt, char* tokStart) + void checkLinkageType(ref LinkageType prev_lt, LinkageType lt, Token* begin) { if (prev_lt == LinkageType.None) prev_lt = lt; else // TODO: create new msg RedundantLinkageType. - error(MID.RedundantStorageClass, tokStart[0 .. prevToken.end - tokStart]); + error(begin, "redundant linkage type: " ~ Token.textSpan(begin, this.prevToken)); } Declaration parseStorageAttribute() @@ -739,7 +744,7 @@ nT(); auto linkageType = parseLinkageType(); - checkLinkageType(prev_linkageType, linkageType, begin.start); + checkLinkageType(prev_linkageType, linkageType, begin); auto saved = this.linkageType; // Save. this.linkageType = linkageType; // Set. @@ -1743,9 +1748,9 @@ else goto case_parseExpressionStatement; // Expression // IntegralType - case T.Char, T.Wchar, T.Dchar, T.Bool, - T.Byte, T.Ubyte, T.Short, T.Ushort, - T.Int, T.Uint, T.Long, T.Ulong, + case T.Char, T.Wchar, T.Dchar, T.Bool, + T.Byte, T.Ubyte, T.Short, T.Ushort, + T.Int, T.Uint, T.Long, T.Ulong, T.Float, T.Double, T.Real, T.Ifloat, T.Idouble, T.Ireal, T.Cfloat, T.Cdouble, T.Creal, T.Void: @@ -1889,10 +1894,10 @@ case T.Typeid: case T.Is: case T.LParen: - // IntegralType - /+case T.Char, T.Wchar, T.Dchar, T.Bool, - T.Byte, T.Ubyte, T.Short, T.Ushort, - T.Int, T.Uint, T.Long, T.Ulong, + /+ // IntegralType + case T.Char, T.Wchar, T.Dchar, T.Bool, + T.Byte, T.Ubyte, T.Short, T.Ushort, + T.Int, T.Uint, T.Long, T.Ulong, T.Float, T.Double, T.Real, T.Ifloat, T.Idouble, T.Ireal, T.Cfloat, T.Cdouble, T.Creal, T.Void:+/ @@ -1919,8 +1924,7 @@ if (token.type != T.Dollar) // Assert that this isn't a valid expression. - assert( - delegate bool(){ + assert(delegate bool(){ bool success; auto expression = try_(&parseExpression, success); return success; @@ -1928,9 +1932,15 @@ ); // Report error: it's an illegal statement. - error(MID.ExpectedButFound, "Statement", token.srcText); - s = new IllegalStatement(token); - nT(); + s = new IllegalStatement(); + // Skip to next valid token. + do + nT(); + while (!token.isStatementStart && + token.type != T.RBrace && + token.type != T.EOF) + auto text = Token.textSpan(begin, this.prevToken); + error(begin, "illegal Statement found: " ~ text); } assert(s !is null); set(s, begin); @@ -2016,7 +2026,7 @@ nT(); auto linkageType = parseLinkageType(); - checkLinkageType(prev_linkageType, linkageType, begin.start); + checkLinkageType(prev_linkageType, linkageType, begin); d = new LinkageDeclaration(linkageType, parse()); break; @@ -2721,9 +2731,15 @@ nT(); break; default: - error(MID.ExpectedButFound, "AsmInstruction", token.srcText); - s = new IllegalAsmInstruction(token); - nT(); + s = new IllegalAsmInstruction(); + // Skip to next valid token. + do + nT(); + while (!token.isAsmInstructionStart && + token.type != T.RBrace && + token.type != T.EOF) + auto text = Token.textSpan(begin, this.prevToken); + error(begin, "illegal AsmInstruction found: " ~ text); } set(s, begin); return s; @@ -3736,9 +3752,9 @@ } break; // IntegralType . Identifier - case T.Char, T.Wchar, T.Dchar, T.Bool, - T.Byte, T.Ubyte, T.Short, T.Ushort, - T.Int, T.Uint, T.Long, T.Ulong, + case T.Char, T.Wchar, T.Dchar, T.Bool, + T.Byte, T.Ubyte, T.Short, T.Ushort, + T.Int, T.Uint, T.Long, T.Ulong, T.Float, T.Double, T.Real, T.Ifloat, T.Idouble, T.Ireal, T.Cfloat, T.Cdouble, T.Creal, T.Void: @@ -3836,9 +3852,9 @@ switch (token.type) { - case T.Char, T.Wchar, T.Dchar, T.Bool, - T.Byte, T.Ubyte, T.Short, T.Ushort, - T.Int, T.Uint, T.Long, T.Ulong, + case T.Char, T.Wchar, T.Dchar, T.Bool, + T.Byte, T.Ubyte, T.Short, T.Ushort, + T.Int, T.Uint, T.Long, T.Ulong, T.Float, T.Double, T.Real, T.Ifloat, T.Idouble, T.Ireal, T.Cfloat, T.Cdouble, T.Creal, T.Void: @@ -4451,15 +4467,26 @@ return null; } + /// Reports an error that has no message ID yet. + void error(Token* token, char[] formatMsg, ...) + { + error_(token, MID.min, formatMsg, _arguments, _argptr); + } + void error(MID mid, ...) { + error_(this.token, mid, GetMsg(mid), _arguments, _argptr); + } + + void error_(Token* token, MID mid, char[] formatMsg, TypeInfo[] _arguments, void* _argptr) + { if (trying) { ++errorCount; return; } - auto location = this.token.getLocation(); - auto msg = Format(_arguments, _argptr, GetMsg(mid)); + auto location = token.getLocation(); + auto msg = Format(_arguments, _argptr, formatMsg); errors ~= new Information(InfoType.Parser, mid, location, msg); } }