annotate python/c3/parser.py @ 148:e5263f74b287

Added c3 language frontend initial parser
author Windel Bouwman
date Fri, 01 Mar 2013 10:24:01 +0100
parents
children 74241ca312cc
rev   line source
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
1 from . import astnodes, lexer, semantics
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
2 from ppci.errors import CompilerException, SourceLocation
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
3
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
4 # binop precedence for expressions:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
5 binopPrecs = {'or': 5, 'and': 10, \
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
6 '<': 20, '>': 20, '==': 20, '<=': 20, '>=': 20, '!=': 20, \
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
7 '+': 30, '-': 30, '*': 40, '/': 40 }
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
8
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
9 def getTokenPrecedence(typ):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
10 if typ in binopPrecs:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
11 return binopPrecs[typ]
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
12 return -1
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
13
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
14 class Parser:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
15 """ Parses sourcecode into an abstract syntax tree (AST) """
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
16 def __init__(self, sema, diag):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
17 self.sema = sema
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
18 self.diag = diag
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
19 def parseSource(self, source):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
20 self.initLex(source)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
21 try:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
22 self.parsePackage()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
23 except CompilerException as e:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
24 self.diag.diag(e)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
25 def Error(self, msg):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
26 raise CompilerException(msg, self.token.loc)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
27 def skipToSemiCol(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
28 while not (self.Peak == ';' or self.Peak == 'END'):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
29 self.NextToken()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
30 # Lexer helpers:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
31 def Consume(self, typ):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
32 if self.Peak == typ:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
33 return self.NextToken()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
34 else:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
35 self.Error('Excected: "{0}", got "{1}"'.format(typ, self.Peak))
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
36 @property
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
37 def Peak(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
38 return self.token.typ
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
39 @property
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
40 def PeakPrec(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
41 return getTokenPrecedence(self.Peak)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
42 def hasConsumed(self, typ):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
43 if self.Peak == typ:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
44 self.Consume(typ)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
45 return True
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
46 return False
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
47 def NextToken(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
48 t = self.token
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
49 if t.typ != 'END':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
50 self.token = self.tokens.__next__()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
51 return t
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
52 def initLex(self, source):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
53 self.tokens = lexer.tokenize(source) # Lexical stage
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
54 self.token = self.tokens.__next__()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
55
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
56 def parsePackage(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
57 self.Consume('package')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
58 name = self.Consume('ID')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
59 self.Consume(';')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
60 self.sema.handlePackage(name.val, name.loc)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
61 # TODO: parse uses
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
62 while self.Peak != 'END':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
63 self.parseTopLevel()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
64 self.Consume('END')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
65
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
66 def parseTopLevel(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
67 is_public = self.hasConsumed('public')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
68 if self.Peak == 'function':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
69 self.parseFunctionDefinition(is_public)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
70 elif self.Peak == 'var':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
71 self.parseVarDef(is_public)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
72
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
73 def parseDesignator(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
74 """ A designator designates an object """
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
75 name = self.Consume('ID')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
76 return name
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
77
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
78 # Type system
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
79 def parseType(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
80 d = self.parseDesignator()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
81 return d
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
82
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
83 # Variable declarations:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
84 def parseVarDef(self, is_public):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
85 self.Consume('var')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
86 typ = self.parseType()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
87 ID = self.Consume('ID')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
88 self.Consume(';')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
89 v = Variable(i.name, typename, public=is_public)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
90 self.curScope.add(v)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
91
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
92 # Procedures
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
93 def parseFunctionDefinition(self, is_pub):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
94 self.Consume('function')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
95 returntype = self.parseType()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
96 procname = self.Consume('ID')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
97 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
98 parameters = []
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
99 if not self.hasConsumed(')'):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
100 typ = self.parseType()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
101 name = self.Consume('ID')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
102 parameters.append(astnodes.Parameter(name, typ))
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
103 while self.hasConsumed(','):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
104 typ = self.parseType()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
105 name = self.Consume('ID')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
106 parameters.append(astnodes.Parameter(name, typ))
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
107 self.Consume(')')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
108 proctyp = astnodes.FunctionType(parameters, returntype)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
109 body = self.parseCompoundStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
110 return astnodes.Procedure(procname, proctyp, body)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
111
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
112 # Statements:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
113 def parseAssignment(self, lval):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
114 self.Consume('=')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
115 rval = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
116 return astnodes.Assignment(lval, rval)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
117
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
118 def parseProcedureCall(self, procedure):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
119 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
120 args = []
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
121 if not self.hasConsumed(')'):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
122 args.append(self.parseExpression())
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
123 while self.hasConsumed(','):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
124 args.append(self.parseExpression())
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
125 self.Consume(')')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
126 return ProcedureCall(procedure, args)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
127
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
128 def parseLocal(self, t):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
129 name = self.Consume('ID')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
130 if self.hasConsumed('='):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
131 ival = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
132 else:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
133 ival = None
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
134 self.sema.actOnLocal(t, name, ival)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
135 def parseLocalDeclaration(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
136 self.Consume('var')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
137 t = self.parseType()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
138 self.parseLocal(t)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
139 while self.hasConsumed(','):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
140 self.parseLocal(t)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
141
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
142 def parseIfStatement(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
143 self.Consume('if')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
144 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
145 condition = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
146 self.Consume(')')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
147 truestatement = self.parseStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
148 if self.hasConsumed('else'):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
149 els = self.parseStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
150 return astnodes.IfStatement(condition, truestatement, els)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
151 return astnodes.IfStatement(condition, truestatement)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
152
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
153 def parseWhileStatement(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
154 self.Consume('while')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
155 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
156 condition = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
157 self.Consume(')')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
158 statements = self.parseStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
159 def parseReturnStatement(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
160 self.Consume('return')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
161 expr = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
162
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
163 def parseCompoundStatement(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
164 self.Consume('{')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
165 statements = [self.parseStatement()]
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
166 while self.hasConsumed(';'):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
167 statements.append(self.parseStatement())
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
168 self.Consume('}')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
169 return astnodes.CompoundStatement(statements)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
170
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
171 def parseStatement(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
172 # Determine statement type based on the pending token:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
173 if self.Peak == 'if':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
174 return self.parseIfStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
175 elif self.Peak == 'while':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
176 return self.parseWhileStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
177 elif self.Peak == '{':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
178 return self.parseCompoundStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
179 elif self.Peak == 'var':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
180 return self.parseLocalDeclaration()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
181 elif self.Peak == 'return':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
182 return self.parseReturnStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
183 elif self.Peak == 'ID':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
184 # Assignment or procedure call
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
185 designator = self.parseDesignator()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
186 if self.Peak == '(':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
187 return self.parseProcedureCall(designator)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
188 elif self.Peak == '=':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
189 return self.parseAssignment(designator)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
190 self.Error('Unable to determine statement')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
191
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
192 # Parsing expressions:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
193 def parseExpression(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
194 return self.parseBinopRhs(self.parsePrimary(), 0)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
195 def parsePrimary(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
196 if self.hasConsumed('('):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
197 e = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
198 self.Consume(')')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
199 return e
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
200 elif self.Peak == 'NUMBER':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
201 val = self.Consume('NUMBER')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
202 return astnodes.Constant(val, val)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
203 elif self.Peak == 'ID':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
204 d = self.parseDesignator()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
205 return d
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
206 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
207
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
208 def parseBinopRhs(self, lhs, min_prec):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
209 while self.PeakPrec >= min_prec:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
210 op_prec = self.PeakPrec
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
211 op = self.Consume(self.Peak)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
212 rhs = self.parsePrimary()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
213 while self.PeakPrec > op_prec:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
214 rhs = self.parseBinopRhs(rhs, self.PeakPrec)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
215 lhs = astnodes.Binop(lhs, op, rhs)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
216 return lhs
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
217