Mercurial > lcfOS
diff python/ppci/c3/parser.py @ 354:5477e499b039
Added some sort of string functionality
author | Windel Bouwman |
---|---|
date | Thu, 13 Mar 2014 18:59:06 +0100 |
parents | d1ecc493384e |
children | c05ab629976a |
line wrap: on
line diff
--- a/python/ppci/c3/parser.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/c3/parser.py Thu Mar 13 18:59:06 2014 +0100 @@ -1,12 +1,12 @@ import logging -from ppci import CompilerError +from .. import CompilerError from .astnodes import Member, Literal, TypeCast, Unop, Binop from .astnodes import Assignment, ExpressionStatement, Compound from .astnodes import Return, While, If, Empty, For from .astnodes import FunctionType, Function, FormalParameter -from .astnodes import StructureType, DefinedType, PointerType +from .astnodes import StructureType, DefinedType, PointerType, ArrayType from .astnodes import Constant, Variable -from .astnodes import StructField, Deref +from .astnodes import StructField, Deref, Index from .astnodes import Package from .astnodes import Identifier from .astnodes import FunctionCall @@ -105,14 +105,29 @@ return ids # Type system - def parseTypeSpec(self): - # For now, do simple type spec, just parse an ID: + def PostFixId(self): + pfe = self.PrimaryExpression_Id() + while self.Peak in ['.']: + if self.hasConsumed('.'): + field = self.Consume('ID') + pfe = Member(pfe, field.val, field.loc) + else: + raise Exception() + return pfe + + def PrimaryExpression_Id(self): + if self.Peak == 'ID': + return self.parseDesignator() + self.Error('Expected ID, got {0}'.format(self.Peak)) + + def parse_type_spec(self): + """ Parse type specification """ if self.Peak == 'struct': self.Consume('struct') self.Consume('{') mems = [] while self.Peak != '}': - mem_t = self.parseTypeSpec() + mem_t = self.parse_type_spec() for i in self.parseIdSequence(): mems.append(StructField(i.val, mem_t)) self.Consume(';') @@ -122,15 +137,27 @@ # TODO) raise NotImplementedError() else: - theT = self.PostFixExpression() - # Check for pointer suffix: - while self.hasConsumed('*'): - theT = PointerType(theT) + theT = self.PostFixId() + + # Check for pointer or array suffix: + while self.Peak in ['*', '[']: + if self.hasConsumed('*'): + theT = PointerType(theT) + elif self.hasConsumed('['): + if self.Peak == ']': + size = 0 + self.Consume(']') + else: + size = self.Expression() + self.Consume(']') + theT = ArrayType(theT, size) + else: + raise Exception() return theT def parseTypeDef(self): self.Consume('type') - newtype = self.parseTypeSpec() + newtype = self.parse_type_spec() typename = self.Consume('ID') self.Consume(';') df = DefinedType(typename.val, newtype, typename.loc) @@ -139,7 +166,7 @@ # Variable declarations: def parseVarDef(self): self.Consume('var') - t = self.parseTypeSpec() + t = self.parse_type_spec() for name in self.parseIdSequence(): v = Variable(name.val, t) v.loc = name.loc @@ -149,7 +176,7 @@ def parseConstDef(self): self.Consume('const') - t = self.parseTypeSpec() + t = self.parse_type_spec() while True: name = self.Consume('ID') self.Consume('=') @@ -163,7 +190,7 @@ def parseFunctionDef(self): loc = self.Consume('function').loc - returntype = self.parseTypeSpec() + returntype = self.parse_type_spec() fname = self.Consume('ID').val f = Function(fname, loc) self.addDeclaration(f) @@ -173,7 +200,7 @@ parameters = [] if not self.hasConsumed(')'): while True: - typ = self.parseTypeSpec() + typ = self.parse_type_spec() name = self.Consume('ID') param = FormalParameter(name.val, typ) param.loc = name.loc @@ -187,7 +214,7 @@ f.body = self.parseCompound() self.currentPart = savePart - def parseIf(self): + def parse_if(self): loc = self.Consume('if').loc self.Consume('(') condition = self.Expression() @@ -204,7 +231,7 @@ statements = self.Statement() return While(condition, statements, loc) - def parseFor(self): + def parse_for(self): loc = self.Consume('for').loc self.Consume('(') init = self.Statement() @@ -235,11 +262,11 @@ def Statement(self): # Determine statement type based on the pending token: if self.Peak == 'if': - return self.parseIf() + return self.parse_if() elif self.Peak == 'while': return self.parseWhile() elif self.Peak == 'for': - return self.parseFor() + return self.parse_for() elif self.Peak == '{': return self.parseCompound() elif self.hasConsumed(';'): @@ -339,7 +366,7 @@ if self.Peak == 'cast': loc = self.Consume('cast').loc self.Consume('<') - t = self.parseTypeSpec() + t = self.parse_type_spec() self.Consume('>') self.Consume('(') ce = self.Expression() @@ -363,7 +390,9 @@ pfe = self.PrimaryExpression() while self.Peak in ['[', '.', '->', '(', '++']: if self.hasConsumed('['): - raise NotImplementedError('Array not yet implemented') + i = self.Expression() + self.Consume(']') + pfe = Index(pfe, i, i.loc) elif self.hasConsumed('->'): field = self.Consume('ID') pfe = Deref(pfe, pfe.loc) @@ -410,3 +439,4 @@ elif self.Peak == 'ID': return self.parseDesignator() self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak)) +