diff parser/Parser.d @ 126:c3b24e7e8cf8

Carius changes to the parser. Parsing attributes, lexing many keywords(not all yet).
author Anders Johnsen <skabet@gmail.com>
date Tue, 27 May 2008 10:32:31 +0200
parents 6a5f745d351c
children 2be29b296081
line wrap: on
line diff
--- a/parser/Parser.d	Sun May 25 21:13:56 2008 +0200
+++ b/parser/Parser.d	Tue May 27 10:32:31 2008 +0200
@@ -5,7 +5,8 @@
 
 import parser.Action;
 
-import basic.Message;
+import basic.Message,
+       basic.Attribute;
 
 import basic.SmallArray,
        basic.SourceManager;
@@ -47,27 +48,88 @@
             m = action.actOnImplicitModule(loc, sm.getFile(loc));
         }
 
+        Attribute att;
         while (lexer.peek.type != Tok.EOF)
-            foreach (d; parseDeclDef())
+            foreach (d; parseDeclDef(&att))
                 action.actOnModuleDecl(m, d);
 
         return m;
     }
 
 private:
-    Decl[] parseDeclDef()
+    Decl[] parseDeclDef(Attribute* a)
     {
         Token t = lexer.peek;
         if (t.type == Tok.Import)
             return parseImports();
         else
-            return [parseDecl()];
+            return [parseDecl(a)];
     }
 
-    Decl parseDecl()
+    Decl parseDecl(Attribute* all_res)
     {
         Token t = lexer.peek;
 
+        Attribute att = *all_res;
+
+        while ( t.isAttribute )
+        {
+            Attribute* a = &att;
+            bool sco;
+            if(lexer.peek(1).type == Tok.Colon)
+                sco = true;
+
+LSwitch:    switch(t.type)
+            {
+                case Tok.Public:
+                    a.setProtection(Protection.Public);
+                    break;
+                case Tok.Private:
+                    a.setProtection(Protection.Private);
+                    break;
+                case Tok.Package:
+                    a.setProtection(Protection.Package);
+                    break;
+                case Tok.Protected:
+                    a.setProtection(Protection.Protected);
+                    break;
+                case Tok.Export:
+                    a.setProtection(Protection.Export);
+                    break;
+                case Tok.Static:
+                    a.setStatic;
+                    break;
+                case Tok.Final:
+                    a.setFinal;
+                    break;
+                case Tok.Const:
+                    a.setConst;
+                    break;
+                case Tok.Abstract:
+                    a.setAbstract;
+                    break;
+                case Tok.Override:
+                    a.setOverride;
+                    break;
+                case Tok.Depracted:
+                    a.setDepracted;
+                    break;
+                case Tok.Auto:
+                    a.setAuto;
+                    break;
+            }
+            if(sco)
+            {
+                sco = false;
+                a = all_res;
+                lexer.next;
+                goto LSwitch;
+            }
+            lexer.next;
+            t = lexer.peek;
+        }
+
+
         if (t.isBasicType || t.isIdentifier)
         {
             Id type;
@@ -82,19 +144,20 @@
                 if (next.type == Tok.Seperator)
                 {
                     Token sep = lexer.next();
-                    return action.actOnDeclarator(type, iden, null);
+                    return action.actOnDeclarator(type, iden, null, att);
                 }
                 else if (next.type == Tok.Assign)
                 {
                     Token assign = lexer.next();
                     Exp exp = parseExpression();
                     require(Tok.Seperator);
-                    return action.actOnDeclarator(type, iden, exp);
+                    return action.actOnDeclarator(type, iden, exp, att);
                 }
                 else if (next.type == Tok.OpenParentheses)
                     return parseFunc(type, iden);
                 else
                     messages.report(UnexpectedTok, next.location).arg(next.getType);
+                return null;
             }
             t = lexer.peek(len);
             messages.report(InvalidDeclType, t.location)
@@ -111,7 +174,7 @@
             Id type = Id(lexer.next);
             Id iden = Id(require(Tok.Identifier));
             
-            return parseStruct(type, iden);
+            return parseStruct(type, iden, att);
         }
         messages.report(UnexpectedTok, t.location)
             .arg(t.getType)
@@ -202,34 +265,17 @@
     /**
       Parse struct
      */
-    Decl parseStruct(Id type, Id iden)
+    Decl parseStruct(Id type, Id iden, Attribute att)
     {
-        auto decl = action.actOnDeclarator(type, iden, null);
+        auto decl = action.actOnDeclarator(type, iden, null, att);
 
         require(Tok.OpenBrace);
 
-        while(lexer.peek.isBasicType || lexer.peek.isIdentifier)
+        Attribute a;
+        while(lexer.peek.isBasicType || lexer.peek.isIdentifier || lexer.peek.isAttribute)
         {
-            auto m_decl = parseDecl();
+            auto m_decl = parseDecl(&a);
             action.actOnStructMember(decl, m_decl); 
-/*            Id var_type = Id(lexer.next);
-            Id var_iden = Id(require(Tok.Identifier));
-            Token next = lexer.peek();
-            if (next.type == Tok.Seperator)
-            {
-                Token sep = lexer.next();
-                action.actOnStructMember(decl, var_type, var_iden, null);
-                continue;
-            }
-            else if (next.type == Tok.Assign)
-            {
-                Token assign = lexer.next();
-                Exp exp = parseExpression();
-                require(Tok.Seperator);
-                action.actOnStructMember(decl, var_type, var_iden, exp);
-                continue;
-            }
-            messages.report(UnexpectedTok, next.location).arg(next.getType);*/
         }
 
         require(Tok.CloseBrace);
@@ -246,54 +292,57 @@
     {
         Token t = lexer.peek;
 
-        switch(t.type)
+        if (t.isReturn)
         {
-            case Tok.Return:
-                Token ret = lexer.next;
-                Exp exp;
-                if (lexer.peek.type != Tok.Seperator)
-                    exp = parseExpression();
-                require(Tok.Seperator);
-                return action.actOnReturnStmt(ret, exp);
+            Token ret = lexer.next;
+            Exp exp;
+            if (lexer.peek.type != Tok.Seperator)
+                exp = parseExpression();
+            require(Tok.Seperator);
+            return action.actOnReturnStmt(ret, exp);
 
             /*
                if (cond)
-                single statement | compound statement
+               single statement | compound statement
                [else
-                single statement | compound statement]
+               single statement | compound statement]
              */
-            case Tok.If:
-                Token _if = lexer.next();
+        }
+        else if (t.isIf)
+        {
+            Token _if = lexer.next();
 
-                require(Tok.OpenParentheses);
-                Exp cond = parseExpression();
-                require(Tok.CloseParentheses);
+            require(Tok.OpenParentheses);
+            Exp cond = parseExpression();
+            require(Tok.CloseParentheses);
 
-                Stmt thenB = parseSingleOrCompoundStatement();
+            Stmt thenB = parseSingleOrCompoundStatement();
 
-                // if there is no else part we use the if as token, to have
-                // something than can be passed along
-                Token _else = _if;
-                Stmt elseB;
-                if (lexer.peek.type == Tok.Else)
-                {
-                    _else = lexer.next;
-                    elseB = parseSingleOrCompoundStatement();
-                }
+            // if there is no else part we use the if as token, to have
+            // something than can be passed along
+            Token _else = _if;
+            Stmt elseB;
+            if (lexer.peek.type == Tok.Else)
+            {
+                _else = lexer.next;
+                elseB = parseSingleOrCompoundStatement();
+            }
 
-                return action.actOnIfStmt(_if, cond, thenB, _else, elseB);
+            return action.actOnIfStmt(_if, cond, thenB, _else, elseB);
 
             /*
                while (cond)
-                single statement | compound statement
+               single statement | compound statement
              */
-            case Tok.While:
-                Token _while = lexer.next;
-                require(Tok.OpenParentheses);
-                Exp cond = parseExpression();
-                require(Tok.CloseParentheses);
-                Stmt bodyStmt = parseSingleOrCompoundStatement();
-                return action.actOnWhileStmt(_while, cond, bodyStmt);
+        }
+        else if (t.isWhile)
+        {
+            Token _while = lexer.next;
+            require(Tok.OpenParentheses);
+            Exp cond = parseExpression();
+            require(Tok.CloseParentheses);
+            Stmt bodyStmt = parseSingleOrCompoundStatement();
+            return action.actOnWhileStmt(_while, cond, bodyStmt);
 
             /*
                One of four things:
@@ -304,48 +353,47 @@
 
                The assignments should be handled as binary expressions?
              */
-            case Tok.Identifier:
-                Token iden = lexer.peek;
-                Token n = lexer.peek(1);
-                // Must be an decl, if we start with a basic type, or two
-                // identifiers in a row
-                if (iden.isBasicType() || iden.isIdentifier())
-                {
-                    if ( n.type == Tok.Star || n.type == Tok.OpenBracket)
-                    {
-                        int len = peekParseType;
-                        if(lexer.peek(len).type == Tok.Identifier && len != 0)
-                            return action.actOnDeclStmt(parseVarDecl());
+        }
+        else if (t.isBasicType || t.isIdentifier)
+        {
+            Token iden = lexer.peek;
+            Token n = lexer.peek(1);
+            // Must be an decl, if we start with a basic type, or two
+            // identifiers in a row
+            if ( n.type == Tok.Star || n.type == Tok.OpenBracket)
+            {
+                int len = peekParseType;
+                if(lexer.peek(len).type == Tok.Identifier && len != 0)
+                    return action.actOnDeclStmt(parseVarDecl());
 
-                        Exp exp = parseExpression();
-                        require(Tok.Seperator);
-                        return action.actOnExprStmt(exp);
-                    }
-                        
-                    if (n.isIdentifier())
-                        return action.actOnDeclStmt(parseVarDecl());
+                Exp exp = parseExpression();
+                require(Tok.Seperator);
+                return action.actOnExprStmt(exp);
+            }
+
+            if (n.isIdentifier())
+                return action.actOnDeclStmt(parseVarDecl());
 
-                    // Expression: a.b, a = b, a(b) etc.
-                    Exp exp = parseExpression();
-                    require(Tok.Seperator);
-                    return action.actOnExprStmt(exp);
-                }
-
-            case Tok.Switch:
-                messages.report(UnexpectedTok, lexer.peek.location).arg(lexer.next.getType);
-                return null;
-
-            default:
-                if (t.isBasicType())
-                    goto case Tok.Identifier;
-                if (t.type == Tok.Star)
-                {
-                    auto exp = parseExpression();
-                    require(Tok.Seperator);
-                    return action.actOnExprStmt(exp);
-                }
-                messages.report(UnexpectedBeginStmt, lexer.peek.location).arg(lexer.next.getType);
-                return null;
+            // Expression: a.b, a = b, a(b) etc.
+            Exp exp = parseExpression();
+            require(Tok.Seperator);
+            return action.actOnExprStmt(exp);
+        }
+        else if(t.isSwitch)
+        {
+            messages.report(UnexpectedTok, lexer.peek.location).arg(lexer.next.getType);
+            return null;
+        }
+        else
+        {
+            if (t.type == Tok.Star)
+            {
+                auto exp = parseExpression();
+                require(Tok.Seperator);
+                return action.actOnExprStmt(exp);
+            }
+            messages.report(UnexpectedBeginStmt, lexer.peek.location).arg(lexer.next.getType);
+            return null;
         }
         messages.report(UnexpectedTok, t.location);
         return null;
@@ -361,7 +409,8 @@
         if (skip(Tok.Assign))
             init = parseExpression();
         require(Tok.Seperator);
-        Decl d = action.actOnDeclarator(type, id, init);
+        Attribute att;
+        Decl d = action.actOnDeclarator(type, id, init, att);
         return d;
     }
 
@@ -676,7 +725,12 @@
 
     static const BinOp[] _binary =
     [
-        {Tok.Assign,    1, false, Operator.Assign},
+        {Tok.Assign,        1, false, Operator.Assign},
+        {Tok.PlusAssign,    1, false, Operator.AddAssign},
+        {Tok.MinusAssign,   1, false, Operator.SubAssign},
+        {Tok.StarAssign,    1, false, Operator.MulAssign},
+        {Tok.SlashAssign,   1, false, Operator.DivAssign},
+        {Tok.PercentAssign, 1, false, Operator.ModAssign},
 
         // =, += etc. 1
         // (need special-case for the ternary operator at this level)