diff python/ppci/c3/parser.py @ 306:b145f8e6050b

Start on c3 rewrite
author Windel Bouwman
date Mon, 09 Dec 2013 19:00:21 +0100
parents 6753763d3bec
children e609d5296ee9
line wrap: on
line diff
--- a/python/ppci/c3/parser.py	Fri Dec 06 13:50:38 2013 +0100
+++ b/python/ppci/c3/parser.py	Mon Dec 09 19:00:21 2013 +0100
@@ -1,15 +1,16 @@
 import logging
 from ppci import CompilerError
-from .lexer import Lexer
-from .astnodes import FieldRef, Literal, TypeCast, Unop, Binop
+from .astnodes import Member, Literal, TypeCast, Unop, Binop
 from .astnodes import Assignment, ExpressionStatement, CompoundStatement
 from .astnodes import ReturnStatement, WhileStatement, IfStatement
 from .astnodes import FunctionType, Function, FormalParameter
 from .astnodes import StructureType, DefinedType, PointerType
 from .astnodes import Constant, Variable
 from .astnodes import StructField, Deref
-from .astnodes import Package, ImportDesignator
-from .astnodes import Designator, VariableUse, FunctionCall
+from .astnodes import Package
+from .astnodes import Identifier
+from .astnodes import FunctionCall
+from .astnodes import EmptyStatement
 
 
 class Parser:
@@ -17,13 +18,14 @@
     def __init__(self, diag):
         self.logger = logging.getLogger('c3')
         self.diag = diag
-        self.lexer = Lexer(diag)
 
-    def parseSource(self, source):
+    def parseSource(self, tokens):
         self.logger.info('Parsing source')
-        self.initLex(source)
+        self.tokens = tokens
+        self.token = self.tokens.__next__()
         try:
             self.parsePackage()
+            self.mod.ok = True  # Valid until proven wrong :)
             return self.mod
         except CompilerError as e:
             self.diag.addDiag(e)
@@ -58,10 +60,6 @@
             self.token = self.tokens.__next__()
         return t
 
-    def initLex(self, source):
-        self.tokens = self.lexer.tokenize(source)
-        self.token = self.tokens.__next__()
-
     def addDeclaration(self, decl):
         self.currentPart.declarations.append(decl)
 
@@ -86,6 +84,7 @@
             self.parseFunctionDef()
         elif self.Peak == 'var':
             self.parseVarDef()
+            # TODO handle variable initialization
         elif self.Peak == 'const':
             self.parseConstDef()
         elif self.Peak == 'type':
@@ -98,11 +97,13 @@
     def parseDesignator(self):
         """ A designator designates an object with a name. """
         name = self.Consume('ID')
-        if self.hasConsumed(':'):
-            name2 = self.Consume('ID')
-            return ImportDesignator(name.val, name2.val, name.loc)
-        else:
-            return Designator(name.val, name.loc)
+        return Identifier(name.val, name.loc)
+
+    def parseIdSequence(self):
+        ids = [self.Consume('ID')]
+        while self.hasConsumed(','):
+            ids.append(self.Consume('ID'))
+        return ids
 
     # Type system
     def parseTypeSpec(self):
@@ -113,16 +114,16 @@
             mems = []
             while self.Peak != '}':
                 mem_t = self.parseTypeSpec()
-                mem_n = self.Consume('ID').val
-                mems.append(StructField(mem_n, mem_t))
-                while self.hasConsumed(','):
-                    mem_n = self.Consume('ID').val
-                    mems.append(StructField(mem_n, mem_t))
+                for i in self.parseIdSequence():
+                    mems.append(StructField(i.val, mem_t))
                 self.Consume(';')
             self.Consume('}')
             theT = StructureType(mems)
+        elif self.Peak == 'enum':
+            # TODO)
+            raise NotImplementedError()
         else:
-            theT = self.parseDesignator()
+            theT = self.PostFixExpression()
         # Check for pointer suffix:
         while self.hasConsumed('*'):
             theT = PointerType(theT)
@@ -140,35 +141,26 @@
     def parseVarDef(self):
         self.Consume('var')
         t = self.parseTypeSpec()
-
-        def parseVar():
-            name = self.Consume('ID')
+        for name in self.parseIdSequence():
             v = Variable(name.val, t)
             v.loc = name.loc
-            if self.hasConsumed('='):
-                v.ival = self.Expression()
             self.addDeclaration(v)
-        parseVar()
-        while self.hasConsumed(','):
-            parseVar()
         self.Consume(';')
+        return EmptyStatement()
 
     def parseConstDef(self):
         self.Consume('const')
         t = self.parseTypeSpec()
-
-        def parseConst():
+        while True:
             name = self.Consume('ID')
             self.Consume('=')
             val = self.Expression()
             c = Constant(name.val, t, val)
             c.loc = name.loc
-        parseConst()
-        while self.hasConsumed(','):
-            parseConst()
+            if not self.hasConsumed(','):
+                break
         self.Consume(';')
 
-    # Procedures
     def parseFunctionDef(self):
         loc = self.Consume('function').loc
         returntype = self.parseTypeSpec()
@@ -180,34 +172,28 @@
         self.Consume('(')
         parameters = []
         if not self.hasConsumed(')'):
-            def parseParameter():
+            while True:
                 typ = self.parseTypeSpec()
                 name = self.Consume('ID')
                 param = FormalParameter(name.val, typ)
                 param.loc = name.loc
                 self.addDeclaration(param)
                 parameters.append(param)
-            parseParameter()
-            while self.hasConsumed(','):
-                parseParameter()
+                if not self.hasConsumed(','):
+                    break
             self.Consume(')')
         paramtypes = [p.typ for p in parameters]
         f.typ = FunctionType(paramtypes, returntype)
         f.body = self.parseCompoundStatement()
         self.currentPart = savePart
 
-    # Statements:
-
     def parseIfStatement(self):
         loc = self.Consume('if').loc
         self.Consume('(')
         condition = self.Expression()
         self.Consume(')')
-        yes = self.parseCompoundStatement()
-        if self.hasConsumed('else'):
-            no = self.parseCompoundStatement()
-        else:
-            no = None
+        yes = self.Statement()
+        no = self.Statement() if self.hasConsumed('else') else EmptyStatement()
         return IfStatement(condition, yes, no, loc)
 
     def parseWhileStatement(self):
@@ -215,7 +201,7 @@
         self.Consume('(')
         condition = self.Expression()
         self.Consume(')')
-        statements = self.parseCompoundStatement()
+        statements = self.Statement()
         return WhileStatement(condition, statements, loc)
 
     def parseReturnStatement(self):
@@ -231,10 +217,7 @@
         self.Consume('{')
         statements = []
         while not self.hasConsumed('}'):
-            s = self.Statement()
-            if s is None:
-                continue
-            statements.append(s)
+            statements.append(self.Statement())
         return CompoundStatement(statements)
 
     def Statement(self):
@@ -246,23 +229,20 @@
         elif self.Peak == '{':
             return self.parseCompoundStatement()
         elif self.hasConsumed(';'):
-            pass
+            return EmptyStatement()
         elif self.Peak == 'var':
-            self.parseVarDef()
+            return self.parseVarDef()
         elif self.Peak == 'return':
             return self.parseReturnStatement()
         else:
-            return self.AssignmentOrCall()
-
-    def AssignmentOrCall(self):
-        x = self.UnaryExpression()
-        if self.Peak == '=':
-            # We enter assignment mode here.
-            loc = self.Consume('=').loc
-            rhs = self.Expression()
-            return Assignment(x, rhs, loc)
-        else:
-            return ExpressionStatement(x, x.loc)
+            x = self.UnaryExpression()
+            if self.Peak == '=':
+                # We enter assignment mode here.
+                loc = self.Consume('=').loc
+                rhs = self.Expression()
+                return Assignment(x, rhs, loc)
+            else:
+                return ExpressionStatement(x, x.loc)
 
     # Expression section:
     # We not implement these C constructs:
@@ -321,7 +301,7 @@
 
     def BitwiseOr(self):
         a = self.BitwiseAnd()
-        while self.Peak in ['|']:
+        while self.Peak == '|':
             op = self.Consume(self.Peak)
             b = self.BitwiseAnd()
             a = Binop(a, op.typ, b, op.loc)
@@ -329,7 +309,7 @@
 
     def BitwiseAnd(self):
         a = self.CastExpression()
-        while self.Peak in ['&']:
+        while self.Peak == '&':
             op = self.Consume(self.Peak)
             b = self.CastExpression()
             a = Binop(a, op.typ, b, op.loc)
@@ -383,12 +363,10 @@
                 elif self.hasConsumed('->'):
                     field = self.Consume('ID')
                     pfe = Deref(pfe, pfe.loc)
-                    pfe = FieldRef(pfe, field.val, field.loc)
+                    pfe = Member(pfe, field.val, field.loc)
                 elif self.hasConsumed('.'):
                     field = self.Consume('ID')
-                    pfe = FieldRef(pfe, field.val, field.loc)
-                else:
-                    raise Exception()
+                    pfe = Member(pfe, field.val, field.loc)
         return pfe
 
     def PrimaryExpression(self):
@@ -409,6 +387,5 @@
             val = self.Consume('false')
             return Literal(False, val.loc)
         elif self.Peak == 'ID':
-            d = self.parseDesignator()
-            return VariableUse(d, d.loc)
+            return self.parseDesignator()
         self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))