changeset 189:75d0544ddc45

Better error handling on unexpected EOF.
author Anders Johnsen <skabet@gmail.com>
date Fri, 25 Jul 2008 13:50:01 +0200
parents b3e0729c8524
children 85e492318bb6
files basic/Message.d basic/Messages.d lexer/Lexer.d lexer/Token.d parser/Parser.d tests/parser/simple_missing_1.d tests/parser/simple_missing_2.d tests/parser/simple_missing_3.d tests/parser/simple_missing_4.d
diffstat 9 files changed, 162 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/basic/Message.d	Fri Jul 25 12:55:38 2008 +0200
+++ b/basic/Message.d	Fri Jul 25 13:50:01 2008 +0200
@@ -156,7 +156,7 @@
         foreach (s ; locs)
         {
             size_t p = src_mgr.getColumn(s.begin);
-            marks[p .. p + (s.end-s.begin)] = '~';
+            marks[p .. p + (s.end-s.begin)] = interests.length ? '~' : '^';
         }
 
         foreach (interest ; interests)
--- a/basic/Messages.d	Fri Jul 25 12:55:38 2008 +0200
+++ b/basic/Messages.d	Fri Jul 25 13:50:01 2008 +0200
@@ -25,6 +25,7 @@
     //   - imports/module
     ExpectedIdAfterPackage,
     RenameMustBeSingleIdent,
+    UnexpectedEOF,
 
 
     // sema
@@ -106,6 +107,7 @@
         InvalidType         : E(Err, "Invalid type"),
         ExpectedIdAfterPackage : E(Err, "Identifier expected following package"),
         UnexpectedLinkType  : E(Err, "Invalid linkage type. Only C, C++, D, Windows, Pascal and System is allowed"),
+        UnexpectedEOF       : E(Err, "Unexpected EOF after '%0'"),
 
         // sema
         CannotFindModule    : E(Err, "Cannot find module '%0'"),
--- a/lexer/Lexer.d	Fri Jul 25 12:55:38 2008 +0200
+++ b/lexer/Lexer.d	Fri Jul 25 13:50:01 2008 +0200
@@ -81,27 +81,34 @@
       */
     Token next()
     {
+        Token res;
         switch (getNextChar)
         {
             case CharType.EOF:
-                SLoc loc;
-                return Token(Tok.EOF, loc+1, 0); 
+                return Token(Tok.EOF, last.location, 0); 
 
             case CharType.Whitespace:
                 position += 1;
-                return this.next;
+                res = this.next;
+                break;
 
             case CharType.Symbol:
-                return lexSymbol;
+                res = lexSymbol;
+                break;
 
             case CharType.Letter:
-                return lexLetter;
+                res = lexLetter;
+                break;
 
             case CharType.Number:
-                return lexNumber;
+                res = lexNumber;
+                break;
             case CharType.Other:
                 messages.report(UnexpectedTok, Loc(position)).fatal(ExitLevel.Lexer);
         }
+        if (res.type != Tok.EOF)
+            last = res;
+        return res;
     }
 
     /**
@@ -121,7 +128,9 @@
         return t;
     }
 
+    Token last;
 private:
+
     Token eq()
     {
         if(source[position] == '=')
--- a/lexer/Token.d	Fri Jul 25 12:55:38 2008 +0200
+++ b/lexer/Token.d	Fri Jul 25 13:50:01 2008 +0200
@@ -1,7 +1,8 @@
 module lexer.Token;
 
 public 
-import basic.SourceLocation;
+import basic.SourceLocation,
+       basic.SourceManager;
 
 import Integer = tango.text.convert.Integer;
 
@@ -34,8 +35,10 @@
     /**
       Get the type of the Token as a string
       */
-    char[] getType ()
+    char[] get (SourceManager sm)
     {
+        if (isIdentifier)
+            return sm.getText(asRange);
         return typeToString[this.type];
     }
 
@@ -44,7 +47,7 @@
       */
     char[] toString ()
     {
-        return this.getType()~": Len: "~Integer.toString(this.length);
+        return typeToString[this.type];
     }
 
     /// Get the range of this token
@@ -247,77 +250,77 @@
     typeToString =
     [
         Tok.EOF:"EOF"[],
-        Tok.Identifier:"Identifier",
-        Tok.Byte:"Byte",
-        Tok.Short:"Short",
-        Tok.Int:"Int",
-        Tok.Long:"Long",
-        Tok.Char:"Char",
-        Tok.Wchar:"Wchar",
-        Tok.Dchar:"Dchar",
-        Tok.Bool:"Bool",
-        Tok.Void:"Void",
-        Tok.Function:"Function",
-        Tok.Eq:"Eq",
-        Tok.Ne:"Ne",
-        Tok.Lt:"Lt",
-        Tok.Le:"Le",
-        Tok.Gt:"Gt",
-        Tok.Ge:"Ge",
-        Tok.OpenParentheses:"OpenParentheses",
-        Tok.CloseParentheses:"CloseParentheses",
-        Tok.OpenBrace:"OpenBrace",
-        Tok.CloseBrace:"CloseBrace",
-        Tok.OpenBracket:"OpenBracket",
-        Tok.CloseBracket:"CloseBracket",
-        Tok.Dot:"Dot",
-        Tok.Assign:"Assign",
-        Tok.Plus:"Plus",
-        Tok.PlusAssign:"PlusAssign",
-        Tok.Minus:"Minus",
-        Tok.MinusAssign:"MinusAssign",
-        Tok.Star:"Star",
-        Tok.StarAssign:"StarAssign",
-        Tok.Slash:"Slash",
-        Tok.SlashAssign:"SlashAssign",
-        Tok.Percent:"Percent",
-        Tok.PercentAssign:"PercentAssign",
-        Tok.LeftShift:"LeftShift",
-        Tok.RightShift:"RightShift",
-        Tok.UnsignedRightShift:"UnsignedRightShift",
-        Tok.Integer:"Integer",
-        Tok.If:"If",
-        Tok.While:"While",
-        Tok.For:"For",
-        Tok.Switch:"Switch",
-        Tok.Case:"Case",
-        Tok.Default:"Default",
-        Tok.Comma:"Comma",
-        Tok.Return:"Return",
-        Tok.Struct:"Struct",
-        Tok.Class:"Class",
-        Tok.This:"This",
-        Tok.Colon:"Colon",
-        Tok.Seperator:"Seperator",
-        Tok.Cast:"Cast",
-        Tok.Module:"Module",
-        Tok.Import:"Import",
+        Tok.Identifier:"identifier",
+        Tok.Byte:"byte",
+        Tok.Short:"short",
+        Tok.Int:"int",
+        Tok.Long:"long",
+        Tok.Char:"char",
+        Tok.Wchar:"wchar",
+        Tok.Dchar:"dchar",
+        Tok.Bool:"bool",
+        Tok.Void:"void",
+        Tok.Function:"function",
+        Tok.Eq:"==",
+        Tok.Ne:"!=",
+        Tok.Lt:"<",
+        Tok.Le:"<=",
+        Tok.Gt:">",
+        Tok.Ge:">=",
+        Tok.OpenParentheses:"(",
+        Tok.CloseParentheses:")",
+        Tok.OpenBrace:"{",
+        Tok.CloseBrace:"}",
+        Tok.OpenBracket:"[",
+        Tok.CloseBracket:"]",
+        Tok.Dot:"-",
+        Tok.Assign:"=",
+        Tok.Plus:"+",
+        Tok.PlusAssign:"+=",
+        Tok.Minus:"-",
+        Tok.MinusAssign:"-=",
+        Tok.Star:"*",
+        Tok.StarAssign:"*=",
+        Tok.Slash:"/",
+        Tok.SlashAssign:"/=",
+        Tok.Percent:"%",
+        Tok.PercentAssign:"%=",
+        Tok.LeftShift:"<<",
+        Tok.RightShift:">>",
+        Tok.UnsignedRightShift:">>>",
+        Tok.Integer:"int",
+        Tok.If:"if",
+        Tok.While:"while",
+        Tok.For:"for",
+        Tok.Switch:"switch",
+        Tok.Case:"case",
+        Tok.Default:"default",
+        Tok.Comma:",",
+        Tok.Return:"return",
+        Tok.Struct:"struct",
+        Tok.Class:"class",
+        Tok.This:"this",
+        Tok.Colon:":",
+        Tok.Seperator:";",
+        Tok.And:"&",
+        Tok.Cast:"cast",
+        Tok.Module:"module",
+        Tok.Import:"import",
         Tok.String:"String",
-        Tok.Public:"Public",
-        Tok.Private:"Private",
-        Tok.Protected:"Protected",
-        Tok.Package:"Package",
-        Tok.Export:"Export",
-        Tok.Static:"Static",
-        Tok.Final:"Finale",
-        Tok.Public:"Public",
-        Tok.Const:"Const",
-        Tok.Abstract:"Abstract",
-        Tok.Override:"Override",
-        Tok.Deprecated:"Deprecated",
-        Tok.Auto:"Auto",
-        Tok.Extern:"Extern",
-        Tok.New:"New",
-        Tok.And:"And"
+        Tok.Public:"public",
+        Tok.Private:"private",
+        Tok.Protected:"protected",
+        Tok.Package:"package",
+        Tok.Export:"export",
+        Tok.Static:"static",
+        Tok.Final:"finale",
+        Tok.Public:"public",
+        Tok.Const:"const",
+        Tok.Abstract:"abstract",
+        Tok.Override:"override",
+        Tok.Deprecated:"deprecated",
+        Tok.Auto:"auto",
+        Tok.Extern:"extern",
+        Tok.New:"new"
     ];
 }
--- a/parser/Parser.d	Fri Jul 25 12:55:38 2008 +0200
+++ b/parser/Parser.d	Fri Jul 25 13:50:01 2008 +0200
@@ -112,8 +112,9 @@
 
                     default:
                         auto n1 = next();
-                        messages.report(UnexpectedTok, n1.location).arg(n1.getType);
-                        return null;
+                        isEOF(type.tok);
+                        messages.report(UnexpectedTok, n1.location).arg(n1.get(sm));
+                        return action.actOnDeclarator(type, iden, null, att);
                 }
                 messages.report(InvalidDeclType, peek.location)
                     .arg(sm.getText(peek.asRange));
@@ -128,7 +129,7 @@
                 return null;
         }
         messages.report(UnexpectedTok, peek.location)
-            .arg(peek.getType)
+            .arg(peek.get(sm))
             .arg(Tok.Identifier)
             .fatal(ExitLevel.Parser);
     }
@@ -692,7 +693,7 @@
                 if (peek.isBasicType)
                     goto case Tok.Void;
 
-                messages.report(UnexpectedBeginStmt, peek.location).arg(peek.getType);
+                messages.report(UnexpectedBeginStmt, peek.location).arg(peek.get(sm));
                 require(Tok.Seperator);
                 return null;
         }
@@ -790,7 +791,7 @@
             return Id(tok);
 
         messages.report(UnexpectedTokSingle, tok.location)
-            .arg(tok.getType)
+            .arg(tok.get(sm))
             .arg(Tok.Identifier);
     }
 
@@ -1128,10 +1129,16 @@
 
     Token require(Tok t)
     {
-        if (peek().type != t)
-            messages.report(UnexpectedTokSingle, peek.location)
-                .arg(peek.getType)
-                .arg(t);
+        if (!isa(t))
+            if(isa(Tok.EOF))
+                messages.report(UnexpectedEOF,
+                    [lexer.last.asRange][], [])
+                    .arg(lexer.last.get(sm))
+                    .fatal(ExitLevel.Parser);
+            else
+                messages.report(UnexpectedTokSingle, peek.location)
+                    .arg(peek.get(sm))
+                    .arg(typeToString[t]);
         return next();
     }
 
@@ -1148,6 +1155,16 @@
         return peek(i).type == t;
     }
 
+    bool isEOF(Token t)
+    {
+        if (isa(Tok.EOF))
+            messages.report(UnexpectedEOF, 
+                    [t.asRange][], [])
+                .arg(t.get(sm))
+                .fatal(ExitLevel.Parser);
+        return false;
+    }
+
     Token next()
     {
         return lexer.next;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/parser/simple_missing_1.d	Fri Jul 25 13:50:01 2008 +0200
@@ -0,0 +1,10 @@
+
+int main(int x)
+{
+    x = 5;
+
+    y = 6 * -x;
+    return x;
+}
+
+int y;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/parser/simple_missing_2.d	Fri Jul 25 13:50:01 2008 +0200
@@ -0,0 +1,11 @@
+//fail
+
+int main(int x)
+{
+    x = 5;
+
+    y = 6 * -x;
+    return x;
+}
+
+int y
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/parser/simple_missing_3.d	Fri Jul 25 13:50:01 2008 +0200
@@ -0,0 +1,11 @@
+//fail
+
+int main(int x)
+{
+    x = 5;
+
+    y = 6 * -x;
+    return x;
+}
+
+int 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/parser/simple_missing_4.d	Fri Jul 25 13:50:01 2008 +0200
@@ -0,0 +1,9 @@
+//fail
+
+int main(int x)
+{
+    x = 5;
+
+    y = 6 * -x;
+    return x;
+