Mercurial > lcfOS
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))