parser.py (9692:67d9da312ef0) parser.py (9773:915be89faf30)
1# Copyright (c) 2009 The Hewlett-Packard Development Company
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Nathan Binkert
28
29import os.path
30import re
31import sys
32
33from m5.util import code_formatter
34from m5.util.grammar import Grammar, ParseError
35
36import slicc.ast as ast
37import slicc.util as util
38from slicc.symbols import SymbolTable
39
40class SLICC(Grammar):
41 def __init__(self, filename, base_dir, verbose=False, traceback=False, **kwargs):
42 self.protocol = None
43 self.traceback = traceback
44 self.verbose = verbose
45 self.symtab = SymbolTable(self)
46 self.base_dir = base_dir
47
48 try:
49 self.decl_list = self.parse_file(filename, **kwargs)
50 except ParseError, e:
51 if not self.traceback:
52 sys.exit(str(e))
53 raise
54
55 def currentLocation(self):
56 return util.Location(self.current_source, self.current_line,
57 no_warning=not self.verbose)
58
59 def codeFormatter(self, *args, **kwargs):
60 code = code_formatter(*args, **kwargs)
61 code['protocol'] = self.protocol
62 return code
63
64 def process(self):
65 self.decl_list.findMachines()
66 self.decl_list.generate()
67
68 def writeCodeFiles(self, code_path, includes):
69 self.symtab.writeCodeFiles(code_path, includes)
70
71 def writeHTMLFiles(self, html_path):
72 self.symtab.writeHTMLFiles(html_path)
73
74 def files(self):
75 f = set([
76 'MachineType.cc',
77 'MachineType.hh',
78 'Types.hh' ])
79
80 f |= self.decl_list.files()
81
82 return f
83
84 t_ignore = '\t '
85
86 # C or C++ comment (ignore)
87 def t_c_comment(self, t):
88 r'/\*(.|\n)*?\*/'
89 t.lexer.lineno += t.value.count('\n')
90
91 def t_cpp_comment(self, t):
92 r'//.*'
93
94 # Define a rule so we can track line numbers
95 def t_newline(self, t):
96 r'\n+'
97 t.lexer.lineno += len(t.value)
98
99 reserved = {
100 'protocol' : 'PROTOCOL',
101 'include' : 'INCLUDE',
102 'global' : 'GLOBAL',
103 'machine' : 'MACHINE',
104 'in_port' : 'IN_PORT',
105 'out_port' : 'OUT_PORT',
106 'action' : 'ACTION',
107 'transition' : 'TRANS',
108 'structure' : 'STRUCT',
109 'external_type' : 'EXTERN_TYPE',
110 'enumeration' : 'ENUM',
111 'state_declaration' : 'STATE_DECL',
112 'peek' : 'PEEK',
113 'stall_and_wait' : 'STALL_AND_WAIT',
114 'enqueue' : 'ENQUEUE',
115 'copy_head' : 'COPY_HEAD',
116 'check_allocate' : 'CHECK_ALLOCATE',
117 'check_stop_slots' : 'CHECK_STOP_SLOTS',
118 'static_cast' : 'STATIC_CAST',
119 'if' : 'IF',
120 'is_valid' : 'IS_VALID',
121 'is_invalid' : 'IS_INVALID',
122 'else' : 'ELSE',
123 'return' : 'RETURN',
124 'void' : 'VOID',
125 'new' : 'NEW',
126 'OOD' : 'OOD',
127 }
128
129 literals = ':[]{}(),='
130
131 tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE',
132 'LEFTSHIFT', 'RIGHTSHIFT',
133 'NOT', 'AND', 'OR',
134 'PLUS', 'DASH', 'STAR', 'SLASH',
135 'INCR', 'DECR',
136 'DOUBLE_COLON', 'SEMI',
137 'ASSIGN', 'DOT',
138 'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ]
139 tokens += reserved.values()
140
141 t_EQ = r'=='
142 t_NE = r'!='
143 t_LT = r'<'
144 t_GT = r'>'
145 t_LE = r'<='
146 t_GE = r'>='
147 t_LEFTSHIFT = r'<<'
148 t_RIGHTSHIFT = r'>>'
149 t_NOT = r'!'
150 t_AND = r'&&'
151 t_OR = r'\|\|'
152 t_PLUS = r'\+'
153 t_DASH = r'-'
154 t_STAR = r'\*'
155 t_SLASH = r'/'
156 t_DOUBLE_COLON = r'::'
157 t_SEMI = r';'
158 t_ASSIGN = r':='
159 t_DOT = r'\.'
160 t_INCR = r'\+\+'
161 t_DECR = r'--'
162
163 precedence = (
164 ('left', 'INCR', 'DECR'),
165 ('left', 'AND', 'OR'),
166 ('left', 'EQ', 'NE'),
167 ('left', 'LT', 'GT', 'LE', 'GE'),
168 ('left', 'RIGHTSHIFT', 'LEFTSHIFT'),
169 ('left', 'PLUS', 'DASH'),
170 ('left', 'STAR', 'SLASH'),
171 ('right', 'NOT', 'UMINUS'),
172 )
173
174 def t_IDENT(self, t):
175 r'[a-zA-Z_][a-zA-Z_0-9]*'
176 if t.value == 'true':
177 t.type = 'LIT_BOOL'
178 t.value = True
179 return t
180
181 if t.value == 'false':
182 t.type = 'LIT_BOOL'
183 t.value = False
184 return t
185
186 # Check for reserved words
187 t.type = self.reserved.get(t.value, 'IDENT')
188 return t
189
190 def t_FLOATNUMBER(self, t):
191 '[0-9]+[.][0-9]+'
192 try:
193 t.value = float(t.value)
194 except ValueError:
195 raise ParseError("Illegal float", t)
196 return t
197
198 def t_NUMBER(self, t):
199 r'[0-9]+'
200 try:
201 t.value = int(t.value)
202 except ValueError:
203 raise ParseError("Illegal number", t)
204 return t
205
206 def t_STRING1(self, t):
207 r'\"[^"\n]*\"'
208 t.type = 'STRING'
209 t.value = t.value[1:-1]
210 return t
211
212 def t_STRING2(self, t):
213 r"\'[^'\n]*\'"
214 t.type = 'STRING'
215 t.value = t.value[1:-1]
216 return t
217
218 def p_file(self, p):
219 "file : decls"
220 p[0] = p[1]
221
222 def p_empty(self, p):
223 "empty :"
224
225 def p_decls(self, p):
226 "decls : declsx"
227 p[0] = ast.DeclListAST(self, p[1])
228
229 def p_declsx__list(self, p):
230 "declsx : decl declsx"
231 if isinstance(p[1], ast.DeclListAST):
232 decls = p[1].decls
233 elif p[1] is None:
234 decls = []
235 else:
236 decls = [ p[1] ]
237 p[0] = decls + p[2]
238
239 def p_declsx__none(self, p):
240 "declsx : empty"
241 p[0] = []
242
243 def p_decl__protocol(self, p):
244 "decl : PROTOCOL STRING SEMI"
245 if self.protocol:
246 msg = "Protocol can only be set once! Error at %s:%s\n" % \
247 (self.current_source, self.current_line)
248 raise ParseError(msg)
249 self.protocol = p[2]
250 p[0] = None
251
252 def p_decl__include(self, p):
253 "decl : INCLUDE STRING SEMI"
254 dirname = os.path.dirname(self.current_source)
255 if os.path.exists(os.path.join(dirname, p[2])):
256 filename = os.path.join(dirname, p[2])
257 else:
258 filename = os.path.join(self.base_dir, p[2])
259 p[0] = self.parse_file(filename)
260
1# Copyright (c) 2009 The Hewlett-Packard Development Company
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Nathan Binkert
28
29import os.path
30import re
31import sys
32
33from m5.util import code_formatter
34from m5.util.grammar import Grammar, ParseError
35
36import slicc.ast as ast
37import slicc.util as util
38from slicc.symbols import SymbolTable
39
40class SLICC(Grammar):
41 def __init__(self, filename, base_dir, verbose=False, traceback=False, **kwargs):
42 self.protocol = None
43 self.traceback = traceback
44 self.verbose = verbose
45 self.symtab = SymbolTable(self)
46 self.base_dir = base_dir
47
48 try:
49 self.decl_list = self.parse_file(filename, **kwargs)
50 except ParseError, e:
51 if not self.traceback:
52 sys.exit(str(e))
53 raise
54
55 def currentLocation(self):
56 return util.Location(self.current_source, self.current_line,
57 no_warning=not self.verbose)
58
59 def codeFormatter(self, *args, **kwargs):
60 code = code_formatter(*args, **kwargs)
61 code['protocol'] = self.protocol
62 return code
63
64 def process(self):
65 self.decl_list.findMachines()
66 self.decl_list.generate()
67
68 def writeCodeFiles(self, code_path, includes):
69 self.symtab.writeCodeFiles(code_path, includes)
70
71 def writeHTMLFiles(self, html_path):
72 self.symtab.writeHTMLFiles(html_path)
73
74 def files(self):
75 f = set([
76 'MachineType.cc',
77 'MachineType.hh',
78 'Types.hh' ])
79
80 f |= self.decl_list.files()
81
82 return f
83
84 t_ignore = '\t '
85
86 # C or C++ comment (ignore)
87 def t_c_comment(self, t):
88 r'/\*(.|\n)*?\*/'
89 t.lexer.lineno += t.value.count('\n')
90
91 def t_cpp_comment(self, t):
92 r'//.*'
93
94 # Define a rule so we can track line numbers
95 def t_newline(self, t):
96 r'\n+'
97 t.lexer.lineno += len(t.value)
98
99 reserved = {
100 'protocol' : 'PROTOCOL',
101 'include' : 'INCLUDE',
102 'global' : 'GLOBAL',
103 'machine' : 'MACHINE',
104 'in_port' : 'IN_PORT',
105 'out_port' : 'OUT_PORT',
106 'action' : 'ACTION',
107 'transition' : 'TRANS',
108 'structure' : 'STRUCT',
109 'external_type' : 'EXTERN_TYPE',
110 'enumeration' : 'ENUM',
111 'state_declaration' : 'STATE_DECL',
112 'peek' : 'PEEK',
113 'stall_and_wait' : 'STALL_AND_WAIT',
114 'enqueue' : 'ENQUEUE',
115 'copy_head' : 'COPY_HEAD',
116 'check_allocate' : 'CHECK_ALLOCATE',
117 'check_stop_slots' : 'CHECK_STOP_SLOTS',
118 'static_cast' : 'STATIC_CAST',
119 'if' : 'IF',
120 'is_valid' : 'IS_VALID',
121 'is_invalid' : 'IS_INVALID',
122 'else' : 'ELSE',
123 'return' : 'RETURN',
124 'void' : 'VOID',
125 'new' : 'NEW',
126 'OOD' : 'OOD',
127 }
128
129 literals = ':[]{}(),='
130
131 tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE',
132 'LEFTSHIFT', 'RIGHTSHIFT',
133 'NOT', 'AND', 'OR',
134 'PLUS', 'DASH', 'STAR', 'SLASH',
135 'INCR', 'DECR',
136 'DOUBLE_COLON', 'SEMI',
137 'ASSIGN', 'DOT',
138 'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ]
139 tokens += reserved.values()
140
141 t_EQ = r'=='
142 t_NE = r'!='
143 t_LT = r'<'
144 t_GT = r'>'
145 t_LE = r'<='
146 t_GE = r'>='
147 t_LEFTSHIFT = r'<<'
148 t_RIGHTSHIFT = r'>>'
149 t_NOT = r'!'
150 t_AND = r'&&'
151 t_OR = r'\|\|'
152 t_PLUS = r'\+'
153 t_DASH = r'-'
154 t_STAR = r'\*'
155 t_SLASH = r'/'
156 t_DOUBLE_COLON = r'::'
157 t_SEMI = r';'
158 t_ASSIGN = r':='
159 t_DOT = r'\.'
160 t_INCR = r'\+\+'
161 t_DECR = r'--'
162
163 precedence = (
164 ('left', 'INCR', 'DECR'),
165 ('left', 'AND', 'OR'),
166 ('left', 'EQ', 'NE'),
167 ('left', 'LT', 'GT', 'LE', 'GE'),
168 ('left', 'RIGHTSHIFT', 'LEFTSHIFT'),
169 ('left', 'PLUS', 'DASH'),
170 ('left', 'STAR', 'SLASH'),
171 ('right', 'NOT', 'UMINUS'),
172 )
173
174 def t_IDENT(self, t):
175 r'[a-zA-Z_][a-zA-Z_0-9]*'
176 if t.value == 'true':
177 t.type = 'LIT_BOOL'
178 t.value = True
179 return t
180
181 if t.value == 'false':
182 t.type = 'LIT_BOOL'
183 t.value = False
184 return t
185
186 # Check for reserved words
187 t.type = self.reserved.get(t.value, 'IDENT')
188 return t
189
190 def t_FLOATNUMBER(self, t):
191 '[0-9]+[.][0-9]+'
192 try:
193 t.value = float(t.value)
194 except ValueError:
195 raise ParseError("Illegal float", t)
196 return t
197
198 def t_NUMBER(self, t):
199 r'[0-9]+'
200 try:
201 t.value = int(t.value)
202 except ValueError:
203 raise ParseError("Illegal number", t)
204 return t
205
206 def t_STRING1(self, t):
207 r'\"[^"\n]*\"'
208 t.type = 'STRING'
209 t.value = t.value[1:-1]
210 return t
211
212 def t_STRING2(self, t):
213 r"\'[^'\n]*\'"
214 t.type = 'STRING'
215 t.value = t.value[1:-1]
216 return t
217
218 def p_file(self, p):
219 "file : decls"
220 p[0] = p[1]
221
222 def p_empty(self, p):
223 "empty :"
224
225 def p_decls(self, p):
226 "decls : declsx"
227 p[0] = ast.DeclListAST(self, p[1])
228
229 def p_declsx__list(self, p):
230 "declsx : decl declsx"
231 if isinstance(p[1], ast.DeclListAST):
232 decls = p[1].decls
233 elif p[1] is None:
234 decls = []
235 else:
236 decls = [ p[1] ]
237 p[0] = decls + p[2]
238
239 def p_declsx__none(self, p):
240 "declsx : empty"
241 p[0] = []
242
243 def p_decl__protocol(self, p):
244 "decl : PROTOCOL STRING SEMI"
245 if self.protocol:
246 msg = "Protocol can only be set once! Error at %s:%s\n" % \
247 (self.current_source, self.current_line)
248 raise ParseError(msg)
249 self.protocol = p[2]
250 p[0] = None
251
252 def p_decl__include(self, p):
253 "decl : INCLUDE STRING SEMI"
254 dirname = os.path.dirname(self.current_source)
255 if os.path.exists(os.path.join(dirname, p[2])):
256 filename = os.path.join(dirname, p[2])
257 else:
258 filename = os.path.join(self.base_dir, p[2])
259 p[0] = self.parse_file(filename)
260
261 def p_decl__machine(self, p):
262 "decl : MACHINE '(' ident pairs ')' ':' params '{' decls '}'"
261 def p_decl__machine0(self, p):
262 "decl : MACHINE '(' idents ')' ':' params '{' decls '}'"
263 p[0] = ast.MachineAST(self, p[3], [], p[7], p[9])
264
265 def p_decl__machine1(self, p):
266 "decl : MACHINE '(' idents pairs ')' ':' params '{' decls '}'"
263 p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9])
264
265 def p_decl__action(self, p):
266 "decl : ACTION '(' ident pairs ')' statements"
267 p[0] = ast.ActionDeclAST(self, p[3], p[4], p[6])
268
269 def p_decl__in_port(self, p):
270 "decl : IN_PORT '(' ident ',' type ',' var pairs ')' statements"
271 p[0] = ast.InPortDeclAST(self, p[3], p[5], p[7], p[8], p[10])
272
273 def p_decl__out_port(self, p):
274 "decl : OUT_PORT '(' ident ',' type ',' var pairs ')' SEMI"
275 p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8])
276
277 def p_decl__trans0(self, p):
278 "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents"
279 p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], p[7], p[8], p[10])
280
281 def p_decl__trans1(self, p):
282 "decl : TRANS '(' idents ',' idents pairs ')' idents"
283 p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], None, p[6], p[8])
284
285 def p_decl__trans2(self, p):
286 "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents idents"
287 p[0] = ast.TransitionDeclAST(self, p[10], p[3], p[5], p[7], p[8], p[11])
288
289 def p_decl__trans3(self, p):
290 "decl : TRANS '(' idents ',' idents pairs ')' idents idents"
291 p[0] = ast.TransitionDeclAST(self, p[8], p[3], p[5], None, p[6], p[9])
292
293 def p_decl__extern0(self, p):
294 "decl : EXTERN_TYPE '(' type pairs ')' SEMI"
295 p[4]["external"] = "yes"
296 p[0] = ast.TypeDeclAST(self, p[3], p[4], [])
297
298 def p_decl__global(self, p):
299 "decl : GLOBAL '(' type pairs ')' '{' type_members '}'"
300 p[4]["global"] = "yes"
301 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
302
303 def p_decl__struct(self, p):
304 "decl : STRUCT '(' type pairs ')' '{' type_members '}'"
305 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
306
307 def p_decl__enum(self, p):
308 "decl : ENUM '(' type pairs ')' '{' type_enums '}'"
309 p[4]["enumeration"] = "yes"
310 p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7])
311
312 def p_decl__state_decl(self, p):
313 "decl : STATE_DECL '(' type pairs ')' '{' type_states '}'"
314 p[4]["enumeration"] = "yes"
315 p[4]["state_decl"] = "yes"
316 p[0] = ast.StateDeclAST(self, p[3], p[4], p[7])
317
318 def p_decl__object(self, p):
319 "decl : type ident pairs SEMI"
320 p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3])
321
322 # Function definition and declaration
323 def p_decl__func_decl(self, p):
324 "decl : func_decl"
325 p[0] = p[1]
326
327 def p_func_decl__0(self, p):
328 """func_decl : void ident '(' params ')' pairs SEMI
329 | type ident '(' params ')' pairs SEMI"""
330 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None)
331
332 def p_decl__func_def(self, p):
333 "decl : func_def"
334 p[0] = p[1]
335
336 def p_func_def__0(self, p):
337 """func_def : void ident '(' params ')' pairs statements
338 | type ident '(' params ')' pairs statements"""
339 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7])
340
341 # Type fields
342 def p_type_members__list(self, p):
343 "type_members : type_member type_members"
344 p[0] = [ p[1] ] + p[2]
345
346 def p_type_members__empty(self, p):
347 "type_members : empty"
348 p[0] = []
349
350 def p_type_method__0(self, p):
351 "type_member : type_or_void ident '(' types ')' pairs SEMI"
352 p[0] = ast.TypeFieldMethodAST(self, p[1], p[2], p[4], p[6])
353
354 def p_type_method__1(self, p):
355 "type_member : type_or_void ident '(' params ')' pairs statements"
356 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7])
357
358 def p_type_member__1(self, p):
359 "type_member : type_or_void ident pairs SEMI"
360 p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], p[3], None)
361
362 def p_type_member__2(self, p):
363 "type_member : type_or_void ident ASSIGN expr SEMI"
364 p[0] = ast.TypeFieldMemberAST(self, p[1], p[2],
365 ast.PairListAST(self), p[4])
366
367 # Enum fields
368 def p_type_enums__list(self, p):
369 "type_enums : type_enum type_enums"
370 p[0] = [ p[1] ] + p[2]
371
372 def p_type_enums__empty(self, p):
373 "type_enums : empty"
374 p[0] = []
375
376 def p_type_enum(self, p):
377 "type_enum : ident pairs SEMI"
378 p[0] = ast.TypeFieldEnumAST(self, p[1], p[2])
379
380 # States
381 def p_type_states__list(self, p):
382 "type_states : type_state type_states"
383 p[0] = [ p[1] ] + p[2]
384
385 def p_type_states__empty(self, p):
386 "type_states : empty"
387 p[0] = []
388
389 def p_type_state(self, p):
390 "type_state : ident ',' enumeration pairs SEMI"
391 p[0] = ast.TypeFieldStateAST(self, p[1], p[3], p[4])
392
393 # Type
394 def p_types__multiple(self, p):
395 "types : type ',' types"
396 p[0] = [ p[1] ] + p[3]
397
398 def p_types__one(self, p):
399 "types : type"
400 p[0] = [ p[1] ]
401
402 def p_types__empty(self, p):
403 "types : empty"
404 p[0] = []
405
406 def p_typestr__multi(self, p):
407 "typestr : typestr DOUBLE_COLON ident"
408 p[0] = '%s::%s' % (p[1], p[3])
409
410 def p_typestr__single(self, p):
411 "typestr : ident"
412 p[0] = p[1]
413
414 def p_type__one(self, p):
415 "type : typestr"
416 p[0] = ast.TypeAST(self, p[1])
417
418 def p_void(self, p):
419 "void : VOID"
420 p[0] = ast.TypeAST(self, p[1])
421
422 def p_type_or_void(self, p):
423 """type_or_void : type
424 | void"""
425 p[0] = p[1]
426
427 # Formal Param
428 def p_params__many(self, p):
429 "params : param ',' params"
430 p[0] = [ p[1] ] + p[3]
431
432 def p_params__one(self, p):
433 "params : param"
434 p[0] = [ p[1] ]
435
436 def p_params__none(self, p):
437 "params : empty"
438 p[0] = []
439
440 def p_param(self, p):
441 "param : type ident"
442 p[0] = ast.FormalParamAST(self, p[1], p[2])
443
444 def p_param__pointer(self, p):
445 "param : type STAR ident"
446 p[0] = ast.FormalParamAST(self, p[1], p[3], None, True)
447
448 def p_param__pointer_default(self, p):
449 "param : type STAR ident '=' STRING"
450 p[0] = ast.FormalParamAST(self, p[1], p[3], p[5], True)
451
452 def p_param__default_number(self, p):
453 "param : type ident '=' NUMBER"
454 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
455
456 def p_param__default_bool(self, p):
457 "param : type ident '=' LIT_BOOL"
458 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
459
460 def p_param__default_string(self, p):
461 "param : type ident '=' STRING"
462 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
463
464 # Idents and lists
465 def p_idents__braced(self, p):
466 "idents : '{' identx '}'"
467 p[0] = p[2]
468
469 def p_idents__bare(self, p):
470 "idents : ident"
471 p[0] = [ p[1] ]
472
473 def p_identx__multiple_1(self, p):
474 """identx : ident SEMI identx
475 | ident ',' identx"""
476 p[0] = [ p[1] ] + p[3]
477
478 def p_identx__multiple_2(self, p):
479 "identx : ident identx"
480 p[0] = [ p[1] ] + p[2]
481
482 def p_identx__single(self, p):
483 "identx : empty"
484 p[0] = [ ]
485
486 def p_ident(self, p):
487 "ident : IDENT"
488 p[0] = p[1]
489
490 # Pair and pair lists
491 def p_pairs__list(self, p):
492 "pairs : ',' pairsx"
493 p[0] = p[2]
494
495 def p_pairs__empty(self, p):
496 "pairs : empty"
497 p[0] = ast.PairListAST(self)
498
499 def p_pairsx__many(self, p):
500 "pairsx : pair ',' pairsx"
501 p[0] = p[3]
502 p[0].addPair(p[1])
503
504 def p_pairsx__one(self, p):
505 "pairsx : pair"
506 p[0] = ast.PairListAST(self)
507 p[0].addPair(p[1])
508
509 def p_pair__assign(self, p):
510 """pair : ident '=' STRING
511 | ident '=' ident
512 | ident '=' NUMBER"""
513 p[0] = ast.PairAST(self, p[1], p[3])
514
515 def p_pair__literal(self, p):
516 "pair : STRING"
517 p[0] = ast.PairAST(self, "short", p[1])
518
519 # Below are the rules for action descriptions
520 def p_statements__inner(self, p):
521 "statements : '{' statements_inner '}'"
522 p[0] = ast.StatementListAST(self, p[2])
523
524 def p_statements__none(self, p):
525 "statements : '{' '}'"
526 p[0] = ast.StatementListAST(self, [])
527
528 def p_statements_inner__many(self, p):
529 "statements_inner : statement statements_inner"
530 p[0] = [ p[1] ] + p[2]
531
532 def p_statements_inner__one(self, p):
533 "statements_inner : statement"
534 p[0] = [ p[1] ]
535
536 def p_exprs__multiple(self, p):
537 "exprs : expr ',' exprs"
538 p[0] = [ p[1] ] + p[3]
539
540 def p_exprs__one(self, p):
541 "exprs : expr"
542 p[0] = [ p[1] ]
543
544 def p_exprs__empty(self, p):
545 "exprs : empty"""
546 p[0] = []
547
548 def p_statement__expression(self, p):
549 "statement : expr SEMI"
550 p[0] = ast.ExprStatementAST(self, p[1])
551
552 def p_statement__assign(self, p):
553 "statement : expr ASSIGN expr SEMI"
554 p[0] = ast.AssignStatementAST(self, p[1], p[3])
555
556 def p_statement__enqueue(self, p):
557 "statement : ENQUEUE '(' var ',' type pairs ')' statements"
558 p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[6], p[8])
559
560 def p_statement__stall_and_wait(self, p):
561 "statement : STALL_AND_WAIT '(' var ',' var ')' SEMI"
562 p[0] = ast.StallAndWaitStatementAST(self, p[3], p[5])
563
564 def p_statement__peek(self, p):
565 "statement : PEEK '(' var ',' type pairs ')' statements"
566 p[0] = ast.PeekStatementAST(self, p[3], p[5], p[6], p[8], "peek")
567
568 def p_statement__copy_head(self, p):
569 "statement : COPY_HEAD '(' var ',' var pairs ')' SEMI"
570 p[0] = ast.CopyHeadStatementAST(self, p[3], p[5], p[6])
571
572 def p_statement__check_allocate(self, p):
573 "statement : CHECK_ALLOCATE '(' var ')' SEMI"
574 p[0] = ast.CheckAllocateStatementAST(self, p[3])
575
576 def p_statement__check_stop(self, p):
577 "statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI"
578 p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7])
579
580 def p_statement__static_cast(self, p):
581 "aexpr : STATIC_CAST '(' type ',' expr ')'"
582 p[0] = ast.StaticCastAST(self, p[3], "ref", p[5])
583
584 def p_statement__static_cast_ptr(self, p):
585 "aexpr : STATIC_CAST '(' type ',' STRING ',' expr ')'"
586 p[0] = ast.StaticCastAST(self, p[3], p[5], p[7])
587
588 def p_statement__return(self, p):
589 "statement : RETURN expr SEMI"
590 p[0] = ast.ReturnStatementAST(self, p[2])
591
592 def p_statement__if(self, p):
593 "statement : if_statement"
594 p[0] = p[1]
595
596 def p_if_statement__if(self, p):
597 "if_statement : IF '(' expr ')' statements"
598 p[0] = ast.IfStatementAST(self, p[3], p[5], None)
599
600 def p_if_statement__if_else(self, p):
601 "if_statement : IF '(' expr ')' statements ELSE statements"
602 p[0] = ast.IfStatementAST(self, p[3], p[5], p[7])
603
604 def p_statement__if_else_if(self, p):
605 "if_statement : IF '(' expr ')' statements ELSE if_statement"
606 p[0] = ast.IfStatementAST(self, p[3], p[5],
607 ast.StatementListAST(self, p[7]))
608
609 def p_expr__var(self, p):
610 "aexpr : var"
611 p[0] = p[1]
612
613 def p_expr__localvar(self, p):
614 "aexpr : type ident"
615 p[0] = ast.LocalVariableAST(self, p[1], p[2])
616
617 def p_expr__literal(self, p):
618 "aexpr : literal"
619 p[0] = p[1]
620
621 def p_expr__enumeration(self, p):
622 "aexpr : enumeration"
623 p[0] = p[1]
624
625 def p_expr__func_call(self, p):
626 "aexpr : ident '(' exprs ')'"
627 p[0] = ast.FuncCallExprAST(self, p[1], p[3])
628
629 def p_expr__new(self, p):
630 "aexpr : NEW type"
631 p[0] = ast.NewExprAST(self, p[2])
632
633 def p_expr__null(self, p):
634 "aexpr : OOD"
635 p[0] = ast.OodAST(self)
636
637 def p_expr__member(self, p):
638 "aexpr : aexpr DOT ident"
639 p[0] = ast.MemberExprAST(self, p[1], p[3])
640
641 def p_expr__member_method_call(self, p):
642 "aexpr : aexpr DOT ident '(' exprs ')'"
643 p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5])
644
645 def p_expr__member_method_call_lookup(self, p):
646 "aexpr : aexpr '[' exprs ']'"
647 p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3])
648
649 def p_expr__class_method_call(self, p):
650 "aexpr : type DOUBLE_COLON ident '(' exprs ')'"
651 p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5])
652
653 def p_expr__aexpr(self, p):
654 "expr : aexpr"
655 p[0] = p[1]
656
657 def p_expr__binary_op(self, p):
658 """expr : expr STAR expr
659 | expr SLASH expr
660 | expr PLUS expr
661 | expr DASH expr
662 | expr LT expr
663 | expr GT expr
664 | expr LE expr
665 | expr GE expr
666 | expr EQ expr
667 | expr NE expr
668 | expr AND expr
669 | expr OR expr
670 | expr RIGHTSHIFT expr
671 | expr LEFTSHIFT expr"""
672 p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3])
673
674 # FIXME - unary not
675 def p_expr__unary_op(self, p):
676 """expr : NOT expr
677 | INCR expr
678 | DECR expr
679 | DASH expr %prec UMINUS"""
680 p[0] = ast.PrefixOperatorExprAST(self, p[1], p[2])
681
682 def p_expr__parens(self, p):
683 "aexpr : '(' expr ')'"
684 p[0] = p[2]
685
686 def p_expr__is_valid_ptr(self, p):
687 "aexpr : IS_VALID '(' var ')'"
688 p[0] = ast.IsValidPtrExprAST(self, p[3], True)
689
690 def p_expr__is_invalid_ptr(self, p):
691 "aexpr : IS_INVALID '(' var ')'"
692 p[0] = ast.IsValidPtrExprAST(self, p[3], False)
693
694 def p_literal__string(self, p):
695 "literal : STRING"
696 p[0] = ast.LiteralExprAST(self, p[1], "std::string")
697
698 def p_literal__number(self, p):
699 "literal : NUMBER"
700 p[0] = ast.LiteralExprAST(self, p[1], "int")
701
702 def p_literal__float(self, p):
703 "literal : FLOATNUMBER"
704 p[0] = ast.LiteralExprAST(self, p[1], "int")
705
706 def p_literal__bool(self, p):
707 "literal : LIT_BOOL"
708 p[0] = ast.LiteralExprAST(self, p[1], "bool")
709
710 def p_enumeration(self, p):
711 "enumeration : ident ':' ident"
712 p[0] = ast.EnumExprAST(self, ast.TypeAST(self, p[1]), p[3])
713
714 def p_var(self, p):
715 "var : ident"
716 p[0] = ast.VarExprAST(self, p[1])
267 p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9])
268
269 def p_decl__action(self, p):
270 "decl : ACTION '(' ident pairs ')' statements"
271 p[0] = ast.ActionDeclAST(self, p[3], p[4], p[6])
272
273 def p_decl__in_port(self, p):
274 "decl : IN_PORT '(' ident ',' type ',' var pairs ')' statements"
275 p[0] = ast.InPortDeclAST(self, p[3], p[5], p[7], p[8], p[10])
276
277 def p_decl__out_port(self, p):
278 "decl : OUT_PORT '(' ident ',' type ',' var pairs ')' SEMI"
279 p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8])
280
281 def p_decl__trans0(self, p):
282 "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents"
283 p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], p[7], p[8], p[10])
284
285 def p_decl__trans1(self, p):
286 "decl : TRANS '(' idents ',' idents pairs ')' idents"
287 p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], None, p[6], p[8])
288
289 def p_decl__trans2(self, p):
290 "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents idents"
291 p[0] = ast.TransitionDeclAST(self, p[10], p[3], p[5], p[7], p[8], p[11])
292
293 def p_decl__trans3(self, p):
294 "decl : TRANS '(' idents ',' idents pairs ')' idents idents"
295 p[0] = ast.TransitionDeclAST(self, p[8], p[3], p[5], None, p[6], p[9])
296
297 def p_decl__extern0(self, p):
298 "decl : EXTERN_TYPE '(' type pairs ')' SEMI"
299 p[4]["external"] = "yes"
300 p[0] = ast.TypeDeclAST(self, p[3], p[4], [])
301
302 def p_decl__global(self, p):
303 "decl : GLOBAL '(' type pairs ')' '{' type_members '}'"
304 p[4]["global"] = "yes"
305 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
306
307 def p_decl__struct(self, p):
308 "decl : STRUCT '(' type pairs ')' '{' type_members '}'"
309 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7])
310
311 def p_decl__enum(self, p):
312 "decl : ENUM '(' type pairs ')' '{' type_enums '}'"
313 p[4]["enumeration"] = "yes"
314 p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7])
315
316 def p_decl__state_decl(self, p):
317 "decl : STATE_DECL '(' type pairs ')' '{' type_states '}'"
318 p[4]["enumeration"] = "yes"
319 p[4]["state_decl"] = "yes"
320 p[0] = ast.StateDeclAST(self, p[3], p[4], p[7])
321
322 def p_decl__object(self, p):
323 "decl : type ident pairs SEMI"
324 p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3])
325
326 # Function definition and declaration
327 def p_decl__func_decl(self, p):
328 "decl : func_decl"
329 p[0] = p[1]
330
331 def p_func_decl__0(self, p):
332 """func_decl : void ident '(' params ')' pairs SEMI
333 | type ident '(' params ')' pairs SEMI"""
334 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None)
335
336 def p_decl__func_def(self, p):
337 "decl : func_def"
338 p[0] = p[1]
339
340 def p_func_def__0(self, p):
341 """func_def : void ident '(' params ')' pairs statements
342 | type ident '(' params ')' pairs statements"""
343 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7])
344
345 # Type fields
346 def p_type_members__list(self, p):
347 "type_members : type_member type_members"
348 p[0] = [ p[1] ] + p[2]
349
350 def p_type_members__empty(self, p):
351 "type_members : empty"
352 p[0] = []
353
354 def p_type_method__0(self, p):
355 "type_member : type_or_void ident '(' types ')' pairs SEMI"
356 p[0] = ast.TypeFieldMethodAST(self, p[1], p[2], p[4], p[6])
357
358 def p_type_method__1(self, p):
359 "type_member : type_or_void ident '(' params ')' pairs statements"
360 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7])
361
362 def p_type_member__1(self, p):
363 "type_member : type_or_void ident pairs SEMI"
364 p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], p[3], None)
365
366 def p_type_member__2(self, p):
367 "type_member : type_or_void ident ASSIGN expr SEMI"
368 p[0] = ast.TypeFieldMemberAST(self, p[1], p[2],
369 ast.PairListAST(self), p[4])
370
371 # Enum fields
372 def p_type_enums__list(self, p):
373 "type_enums : type_enum type_enums"
374 p[0] = [ p[1] ] + p[2]
375
376 def p_type_enums__empty(self, p):
377 "type_enums : empty"
378 p[0] = []
379
380 def p_type_enum(self, p):
381 "type_enum : ident pairs SEMI"
382 p[0] = ast.TypeFieldEnumAST(self, p[1], p[2])
383
384 # States
385 def p_type_states__list(self, p):
386 "type_states : type_state type_states"
387 p[0] = [ p[1] ] + p[2]
388
389 def p_type_states__empty(self, p):
390 "type_states : empty"
391 p[0] = []
392
393 def p_type_state(self, p):
394 "type_state : ident ',' enumeration pairs SEMI"
395 p[0] = ast.TypeFieldStateAST(self, p[1], p[3], p[4])
396
397 # Type
398 def p_types__multiple(self, p):
399 "types : type ',' types"
400 p[0] = [ p[1] ] + p[3]
401
402 def p_types__one(self, p):
403 "types : type"
404 p[0] = [ p[1] ]
405
406 def p_types__empty(self, p):
407 "types : empty"
408 p[0] = []
409
410 def p_typestr__multi(self, p):
411 "typestr : typestr DOUBLE_COLON ident"
412 p[0] = '%s::%s' % (p[1], p[3])
413
414 def p_typestr__single(self, p):
415 "typestr : ident"
416 p[0] = p[1]
417
418 def p_type__one(self, p):
419 "type : typestr"
420 p[0] = ast.TypeAST(self, p[1])
421
422 def p_void(self, p):
423 "void : VOID"
424 p[0] = ast.TypeAST(self, p[1])
425
426 def p_type_or_void(self, p):
427 """type_or_void : type
428 | void"""
429 p[0] = p[1]
430
431 # Formal Param
432 def p_params__many(self, p):
433 "params : param ',' params"
434 p[0] = [ p[1] ] + p[3]
435
436 def p_params__one(self, p):
437 "params : param"
438 p[0] = [ p[1] ]
439
440 def p_params__none(self, p):
441 "params : empty"
442 p[0] = []
443
444 def p_param(self, p):
445 "param : type ident"
446 p[0] = ast.FormalParamAST(self, p[1], p[2])
447
448 def p_param__pointer(self, p):
449 "param : type STAR ident"
450 p[0] = ast.FormalParamAST(self, p[1], p[3], None, True)
451
452 def p_param__pointer_default(self, p):
453 "param : type STAR ident '=' STRING"
454 p[0] = ast.FormalParamAST(self, p[1], p[3], p[5], True)
455
456 def p_param__default_number(self, p):
457 "param : type ident '=' NUMBER"
458 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
459
460 def p_param__default_bool(self, p):
461 "param : type ident '=' LIT_BOOL"
462 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
463
464 def p_param__default_string(self, p):
465 "param : type ident '=' STRING"
466 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4])
467
468 # Idents and lists
469 def p_idents__braced(self, p):
470 "idents : '{' identx '}'"
471 p[0] = p[2]
472
473 def p_idents__bare(self, p):
474 "idents : ident"
475 p[0] = [ p[1] ]
476
477 def p_identx__multiple_1(self, p):
478 """identx : ident SEMI identx
479 | ident ',' identx"""
480 p[0] = [ p[1] ] + p[3]
481
482 def p_identx__multiple_2(self, p):
483 "identx : ident identx"
484 p[0] = [ p[1] ] + p[2]
485
486 def p_identx__single(self, p):
487 "identx : empty"
488 p[0] = [ ]
489
490 def p_ident(self, p):
491 "ident : IDENT"
492 p[0] = p[1]
493
494 # Pair and pair lists
495 def p_pairs__list(self, p):
496 "pairs : ',' pairsx"
497 p[0] = p[2]
498
499 def p_pairs__empty(self, p):
500 "pairs : empty"
501 p[0] = ast.PairListAST(self)
502
503 def p_pairsx__many(self, p):
504 "pairsx : pair ',' pairsx"
505 p[0] = p[3]
506 p[0].addPair(p[1])
507
508 def p_pairsx__one(self, p):
509 "pairsx : pair"
510 p[0] = ast.PairListAST(self)
511 p[0].addPair(p[1])
512
513 def p_pair__assign(self, p):
514 """pair : ident '=' STRING
515 | ident '=' ident
516 | ident '=' NUMBER"""
517 p[0] = ast.PairAST(self, p[1], p[3])
518
519 def p_pair__literal(self, p):
520 "pair : STRING"
521 p[0] = ast.PairAST(self, "short", p[1])
522
523 # Below are the rules for action descriptions
524 def p_statements__inner(self, p):
525 "statements : '{' statements_inner '}'"
526 p[0] = ast.StatementListAST(self, p[2])
527
528 def p_statements__none(self, p):
529 "statements : '{' '}'"
530 p[0] = ast.StatementListAST(self, [])
531
532 def p_statements_inner__many(self, p):
533 "statements_inner : statement statements_inner"
534 p[0] = [ p[1] ] + p[2]
535
536 def p_statements_inner__one(self, p):
537 "statements_inner : statement"
538 p[0] = [ p[1] ]
539
540 def p_exprs__multiple(self, p):
541 "exprs : expr ',' exprs"
542 p[0] = [ p[1] ] + p[3]
543
544 def p_exprs__one(self, p):
545 "exprs : expr"
546 p[0] = [ p[1] ]
547
548 def p_exprs__empty(self, p):
549 "exprs : empty"""
550 p[0] = []
551
552 def p_statement__expression(self, p):
553 "statement : expr SEMI"
554 p[0] = ast.ExprStatementAST(self, p[1])
555
556 def p_statement__assign(self, p):
557 "statement : expr ASSIGN expr SEMI"
558 p[0] = ast.AssignStatementAST(self, p[1], p[3])
559
560 def p_statement__enqueue(self, p):
561 "statement : ENQUEUE '(' var ',' type pairs ')' statements"
562 p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[6], p[8])
563
564 def p_statement__stall_and_wait(self, p):
565 "statement : STALL_AND_WAIT '(' var ',' var ')' SEMI"
566 p[0] = ast.StallAndWaitStatementAST(self, p[3], p[5])
567
568 def p_statement__peek(self, p):
569 "statement : PEEK '(' var ',' type pairs ')' statements"
570 p[0] = ast.PeekStatementAST(self, p[3], p[5], p[6], p[8], "peek")
571
572 def p_statement__copy_head(self, p):
573 "statement : COPY_HEAD '(' var ',' var pairs ')' SEMI"
574 p[0] = ast.CopyHeadStatementAST(self, p[3], p[5], p[6])
575
576 def p_statement__check_allocate(self, p):
577 "statement : CHECK_ALLOCATE '(' var ')' SEMI"
578 p[0] = ast.CheckAllocateStatementAST(self, p[3])
579
580 def p_statement__check_stop(self, p):
581 "statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI"
582 p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7])
583
584 def p_statement__static_cast(self, p):
585 "aexpr : STATIC_CAST '(' type ',' expr ')'"
586 p[0] = ast.StaticCastAST(self, p[3], "ref", p[5])
587
588 def p_statement__static_cast_ptr(self, p):
589 "aexpr : STATIC_CAST '(' type ',' STRING ',' expr ')'"
590 p[0] = ast.StaticCastAST(self, p[3], p[5], p[7])
591
592 def p_statement__return(self, p):
593 "statement : RETURN expr SEMI"
594 p[0] = ast.ReturnStatementAST(self, p[2])
595
596 def p_statement__if(self, p):
597 "statement : if_statement"
598 p[0] = p[1]
599
600 def p_if_statement__if(self, p):
601 "if_statement : IF '(' expr ')' statements"
602 p[0] = ast.IfStatementAST(self, p[3], p[5], None)
603
604 def p_if_statement__if_else(self, p):
605 "if_statement : IF '(' expr ')' statements ELSE statements"
606 p[0] = ast.IfStatementAST(self, p[3], p[5], p[7])
607
608 def p_statement__if_else_if(self, p):
609 "if_statement : IF '(' expr ')' statements ELSE if_statement"
610 p[0] = ast.IfStatementAST(self, p[3], p[5],
611 ast.StatementListAST(self, p[7]))
612
613 def p_expr__var(self, p):
614 "aexpr : var"
615 p[0] = p[1]
616
617 def p_expr__localvar(self, p):
618 "aexpr : type ident"
619 p[0] = ast.LocalVariableAST(self, p[1], p[2])
620
621 def p_expr__literal(self, p):
622 "aexpr : literal"
623 p[0] = p[1]
624
625 def p_expr__enumeration(self, p):
626 "aexpr : enumeration"
627 p[0] = p[1]
628
629 def p_expr__func_call(self, p):
630 "aexpr : ident '(' exprs ')'"
631 p[0] = ast.FuncCallExprAST(self, p[1], p[3])
632
633 def p_expr__new(self, p):
634 "aexpr : NEW type"
635 p[0] = ast.NewExprAST(self, p[2])
636
637 def p_expr__null(self, p):
638 "aexpr : OOD"
639 p[0] = ast.OodAST(self)
640
641 def p_expr__member(self, p):
642 "aexpr : aexpr DOT ident"
643 p[0] = ast.MemberExprAST(self, p[1], p[3])
644
645 def p_expr__member_method_call(self, p):
646 "aexpr : aexpr DOT ident '(' exprs ')'"
647 p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5])
648
649 def p_expr__member_method_call_lookup(self, p):
650 "aexpr : aexpr '[' exprs ']'"
651 p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3])
652
653 def p_expr__class_method_call(self, p):
654 "aexpr : type DOUBLE_COLON ident '(' exprs ')'"
655 p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5])
656
657 def p_expr__aexpr(self, p):
658 "expr : aexpr"
659 p[0] = p[1]
660
661 def p_expr__binary_op(self, p):
662 """expr : expr STAR expr
663 | expr SLASH expr
664 | expr PLUS expr
665 | expr DASH expr
666 | expr LT expr
667 | expr GT expr
668 | expr LE expr
669 | expr GE expr
670 | expr EQ expr
671 | expr NE expr
672 | expr AND expr
673 | expr OR expr
674 | expr RIGHTSHIFT expr
675 | expr LEFTSHIFT expr"""
676 p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3])
677
678 # FIXME - unary not
679 def p_expr__unary_op(self, p):
680 """expr : NOT expr
681 | INCR expr
682 | DECR expr
683 | DASH expr %prec UMINUS"""
684 p[0] = ast.PrefixOperatorExprAST(self, p[1], p[2])
685
686 def p_expr__parens(self, p):
687 "aexpr : '(' expr ')'"
688 p[0] = p[2]
689
690 def p_expr__is_valid_ptr(self, p):
691 "aexpr : IS_VALID '(' var ')'"
692 p[0] = ast.IsValidPtrExprAST(self, p[3], True)
693
694 def p_expr__is_invalid_ptr(self, p):
695 "aexpr : IS_INVALID '(' var ')'"
696 p[0] = ast.IsValidPtrExprAST(self, p[3], False)
697
698 def p_literal__string(self, p):
699 "literal : STRING"
700 p[0] = ast.LiteralExprAST(self, p[1], "std::string")
701
702 def p_literal__number(self, p):
703 "literal : NUMBER"
704 p[0] = ast.LiteralExprAST(self, p[1], "int")
705
706 def p_literal__float(self, p):
707 "literal : FLOATNUMBER"
708 p[0] = ast.LiteralExprAST(self, p[1], "int")
709
710 def p_literal__bool(self, p):
711 "literal : LIT_BOOL"
712 p[0] = ast.LiteralExprAST(self, p[1], "bool")
713
714 def p_enumeration(self, p):
715 "enumeration : ident ':' ident"
716 p[0] = ast.EnumExprAST(self, ast.TypeAST(self, p[1]), p[3])
717
718 def p_var(self, p):
719 "var : ident"
720 p[0] = ast.VarExprAST(self, p[1])