parser.py revision 10964
113511Sgabeblack@google.com# Copyright (c) 2009 The Hewlett-Packard Development Company 213511Sgabeblack@google.com# All rights reserved. 313511Sgabeblack@google.com# 413511Sgabeblack@google.com# Redistribution and use in source and binary forms, with or without 513511Sgabeblack@google.com# modification, are permitted provided that the following conditions are 613511Sgabeblack@google.com# met: redistributions of source code must retain the above copyright 713511Sgabeblack@google.com# notice, this list of conditions and the following disclaimer; 813511Sgabeblack@google.com# redistributions in binary form must reproduce the above copyright 913511Sgabeblack@google.com# notice, this list of conditions and the following disclaimer in the 1013511Sgabeblack@google.com# documentation and/or other materials provided with the distribution; 1113511Sgabeblack@google.com# neither the name of the copyright holders nor the names of its 1213511Sgabeblack@google.com# contributors may be used to endorse or promote products derived from 1313511Sgabeblack@google.com# this software without specific prior written permission. 1413511Sgabeblack@google.com# 1513511Sgabeblack@google.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1613511Sgabeblack@google.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1713511Sgabeblack@google.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1813511Sgabeblack@google.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1913511Sgabeblack@google.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2013511Sgabeblack@google.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2113511Sgabeblack@google.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2213511Sgabeblack@google.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2313511Sgabeblack@google.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2413511Sgabeblack@google.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2513511Sgabeblack@google.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2613511Sgabeblack@google.com# 2713511Sgabeblack@google.com# Authors: Nathan Binkert 2813511Sgabeblack@google.com 2913511Sgabeblack@google.comimport os.path 3013511Sgabeblack@google.comimport re 3113511Sgabeblack@google.comimport sys 3213511Sgabeblack@google.com 3313511Sgabeblack@google.comfrom m5.util import code_formatter 3413511Sgabeblack@google.comfrom m5.util.grammar import Grammar, ParseError 3513511Sgabeblack@google.com 3613511Sgabeblack@google.comimport slicc.ast as ast 3713511Sgabeblack@google.comimport slicc.util as util 3813511Sgabeblack@google.comfrom slicc.symbols import SymbolTable 3913511Sgabeblack@google.com 4013511Sgabeblack@google.comclass SLICC(Grammar): 4113511Sgabeblack@google.com def __init__(self, filename, base_dir, verbose=False, traceback=False, **kwargs): 4213511Sgabeblack@google.com self.protocol = None 4313511Sgabeblack@google.com self.traceback = traceback 4413511Sgabeblack@google.com self.verbose = verbose 4513511Sgabeblack@google.com self.symtab = SymbolTable(self) 4613511Sgabeblack@google.com self.base_dir = base_dir 4713511Sgabeblack@google.com 4813511Sgabeblack@google.com try: 4913511Sgabeblack@google.com self.decl_list = self.parse_file(filename, **kwargs) 5013511Sgabeblack@google.com except ParseError, e: 5113511Sgabeblack@google.com if not self.traceback: 5213511Sgabeblack@google.com sys.exit(str(e)) 5313511Sgabeblack@google.com raise 5413511Sgabeblack@google.com 5513511Sgabeblack@google.com def currentLocation(self): 5613511Sgabeblack@google.com return util.Location(self.current_source, self.current_line, 5713511Sgabeblack@google.com no_warning=not self.verbose) 5813511Sgabeblack@google.com 5913511Sgabeblack@google.com def codeFormatter(self, *args, **kwargs): 6013511Sgabeblack@google.com code = code_formatter(*args, **kwargs) 6113511Sgabeblack@google.com code['protocol'] = self.protocol 6213511Sgabeblack@google.com return code 6313511Sgabeblack@google.com 6413511Sgabeblack@google.com def process(self): 6513511Sgabeblack@google.com self.decl_list.findMachines() 6613511Sgabeblack@google.com self.decl_list.generate() 6713511Sgabeblack@google.com 6813511Sgabeblack@google.com def writeCodeFiles(self, code_path, includes): 6913511Sgabeblack@google.com self.symtab.writeCodeFiles(code_path, includes) 7013511Sgabeblack@google.com 7113511Sgabeblack@google.com def writeHTMLFiles(self, html_path): 7213511Sgabeblack@google.com self.symtab.writeHTMLFiles(html_path) 7313511Sgabeblack@google.com 7413511Sgabeblack@google.com def files(self): 7513511Sgabeblack@google.com f = set([ 7613511Sgabeblack@google.com 'MachineType.cc', 7713511Sgabeblack@google.com 'MachineType.hh', 7813511Sgabeblack@google.com 'Types.hh' ]) 7913511Sgabeblack@google.com 8013511Sgabeblack@google.com f |= self.decl_list.files() 8113511Sgabeblack@google.com 8213511Sgabeblack@google.com return f 8313511Sgabeblack@google.com 8413511Sgabeblack@google.com t_ignore = '\t ' 8513511Sgabeblack@google.com 8613511Sgabeblack@google.com # C or C++ comment (ignore) 8713511Sgabeblack@google.com def t_c_comment(self, t): 8813511Sgabeblack@google.com r'/\*(.|\n)*?\*/' 8913511Sgabeblack@google.com t.lexer.lineno += t.value.count('\n') 9013511Sgabeblack@google.com 9113511Sgabeblack@google.com def t_cpp_comment(self, t): 9213511Sgabeblack@google.com r'//.*' 9313511Sgabeblack@google.com 9413511Sgabeblack@google.com # Define a rule so we can track line numbers 9513511Sgabeblack@google.com def t_newline(self, t): 9613511Sgabeblack@google.com r'\n+' 9713511Sgabeblack@google.com t.lexer.lineno += len(t.value) 9813511Sgabeblack@google.com 9913511Sgabeblack@google.com reserved = { 10013511Sgabeblack@google.com 'protocol' : 'PROTOCOL', 10113511Sgabeblack@google.com 'include' : 'INCLUDE', 10213511Sgabeblack@google.com 'global' : 'GLOBAL', 10313511Sgabeblack@google.com 'machine' : 'MACHINE', 10413511Sgabeblack@google.com 'in_port' : 'IN_PORT', 10513511Sgabeblack@google.com 'out_port' : 'OUT_PORT', 10613511Sgabeblack@google.com 'action' : 'ACTION', 10713511Sgabeblack@google.com 'transition' : 'TRANS', 10813511Sgabeblack@google.com 'structure' : 'STRUCT', 10913511Sgabeblack@google.com 'external_type' : 'EXTERN_TYPE', 11013511Sgabeblack@google.com 'enumeration' : 'ENUM', 11113511Sgabeblack@google.com 'state_declaration' : 'STATE_DECL', 11213511Sgabeblack@google.com 'peek' : 'PEEK', 11313511Sgabeblack@google.com 'stall_and_wait' : 'STALL_AND_WAIT', 11413511Sgabeblack@google.com 'enqueue' : 'ENQUEUE', 11513511Sgabeblack@google.com 'check_allocate' : 'CHECK_ALLOCATE', 11613511Sgabeblack@google.com 'check_stop_slots' : 'CHECK_STOP_SLOTS', 11713511Sgabeblack@google.com 'static_cast' : 'STATIC_CAST', 11813511Sgabeblack@google.com 'if' : 'IF', 11913511Sgabeblack@google.com 'is_valid' : 'IS_VALID', 12013511Sgabeblack@google.com 'is_invalid' : 'IS_INVALID', 12113511Sgabeblack@google.com 'else' : 'ELSE', 12213511Sgabeblack@google.com 'return' : 'RETURN', 12313511Sgabeblack@google.com 'void' : 'VOID', 12413511Sgabeblack@google.com 'new' : 'NEW', 12513511Sgabeblack@google.com 'OOD' : 'OOD', 12613511Sgabeblack@google.com } 12713511Sgabeblack@google.com 12813511Sgabeblack@google.com literals = ':[]{}(),=' 12913511Sgabeblack@google.com 13013511Sgabeblack@google.com tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE', 13113511Sgabeblack@google.com 'LEFTSHIFT', 'RIGHTSHIFT', 13213511Sgabeblack@google.com 'NOT', 'AND', 'OR', 13313511Sgabeblack@google.com 'PLUS', 'DASH', 'STAR', 'SLASH', 13413511Sgabeblack@google.com 'INCR', 'DECR', 13513511Sgabeblack@google.com 'DOUBLE_COLON', 'SEMI', 13613511Sgabeblack@google.com 'ASSIGN', 'DOT', 13713511Sgabeblack@google.com 'IDENT', 'LIT_BOOL', 'FLOATNUMBER', 'NUMBER', 'STRING' ] 13813511Sgabeblack@google.com tokens += reserved.values() 13913511Sgabeblack@google.com 14013511Sgabeblack@google.com t_EQ = r'==' 14113511Sgabeblack@google.com t_NE = r'!=' 14213511Sgabeblack@google.com t_LT = r'<' 14313511Sgabeblack@google.com t_GT = r'>' 14413511Sgabeblack@google.com t_LE = r'<=' 14513511Sgabeblack@google.com t_GE = r'>=' 14613511Sgabeblack@google.com t_LEFTSHIFT = r'<<' 14713511Sgabeblack@google.com t_RIGHTSHIFT = r'>>' 14813511Sgabeblack@google.com t_NOT = r'!' 14913511Sgabeblack@google.com t_AND = r'&&' 15013511Sgabeblack@google.com t_OR = r'\|\|' 15113511Sgabeblack@google.com t_PLUS = r'\+' 15213511Sgabeblack@google.com t_DASH = r'-' 15313511Sgabeblack@google.com t_STAR = r'\*' 15413511Sgabeblack@google.com t_SLASH = r'/' 15513511Sgabeblack@google.com t_DOUBLE_COLON = r'::' 15613511Sgabeblack@google.com t_SEMI = r';' 15713511Sgabeblack@google.com t_ASSIGN = r':=' 15813511Sgabeblack@google.com t_DOT = r'\.' 15913511Sgabeblack@google.com t_INCR = r'\+\+' 16013511Sgabeblack@google.com t_DECR = r'--' 16113511Sgabeblack@google.com 16213511Sgabeblack@google.com precedence = ( 16313511Sgabeblack@google.com ('left', 'INCR', 'DECR'), 16413511Sgabeblack@google.com ('left', 'AND', 'OR'), 16513511Sgabeblack@google.com ('left', 'EQ', 'NE'), 16613511Sgabeblack@google.com ('left', 'LT', 'GT', 'LE', 'GE'), 16713511Sgabeblack@google.com ('left', 'RIGHTSHIFT', 'LEFTSHIFT'), 16813511Sgabeblack@google.com ('left', 'PLUS', 'DASH'), 16913511Sgabeblack@google.com ('left', 'STAR', 'SLASH'), 17013511Sgabeblack@google.com ('right', 'NOT', 'UMINUS'), 17113511Sgabeblack@google.com ) 17213511Sgabeblack@google.com 17313511Sgabeblack@google.com def t_IDENT(self, t): 17413511Sgabeblack@google.com r'[a-zA-Z_][a-zA-Z_0-9]*' 175 if t.value == 'true': 176 t.type = 'LIT_BOOL' 177 t.value = True 178 return t 179 180 if t.value == 'false': 181 t.type = 'LIT_BOOL' 182 t.value = False 183 return t 184 185 # Check for reserved words 186 t.type = self.reserved.get(t.value, 'IDENT') 187 return t 188 189 def t_FLOATNUMBER(self, t): 190 '[0-9]+[.][0-9]+' 191 try: 192 t.value = float(t.value) 193 except ValueError: 194 raise ParseError("Illegal float", t) 195 return t 196 197 def t_NUMBER(self, t): 198 r'[0-9]+' 199 try: 200 t.value = int(t.value) 201 except ValueError: 202 raise ParseError("Illegal number", t) 203 return t 204 205 def t_STRING1(self, t): 206 r'\"[^"\n]*\"' 207 t.type = 'STRING' 208 t.value = t.value[1:-1] 209 return t 210 211 def t_STRING2(self, t): 212 r"\'[^'\n]*\'" 213 t.type = 'STRING' 214 t.value = t.value[1:-1] 215 return t 216 217 def p_file(self, p): 218 "file : decls" 219 p[0] = p[1] 220 221 def p_empty(self, p): 222 "empty :" 223 224 def p_decls(self, p): 225 "decls : declsx" 226 p[0] = ast.DeclListAST(self, p[1]) 227 228 def p_declsx__list(self, p): 229 "declsx : decl declsx" 230 if isinstance(p[1], ast.DeclListAST): 231 decls = p[1].decls 232 elif p[1] is None: 233 decls = [] 234 else: 235 decls = [ p[1] ] 236 p[0] = decls + p[2] 237 238 def p_declsx__none(self, p): 239 "declsx : empty" 240 p[0] = [] 241 242 def p_decl__protocol(self, p): 243 "decl : PROTOCOL STRING SEMI" 244 if self.protocol: 245 msg = "Protocol can only be set once! Error at %s:%s\n" % \ 246 (self.current_source, self.current_line) 247 raise ParseError(msg) 248 self.protocol = p[2] 249 p[0] = None 250 251 def p_decl__include(self, p): 252 "decl : INCLUDE STRING SEMI" 253 dirname = os.path.dirname(self.current_source) 254 if os.path.exists(os.path.join(dirname, p[2])): 255 filename = os.path.join(dirname, p[2]) 256 else: 257 filename = os.path.join(self.base_dir, p[2]) 258 p[0] = self.parse_file(filename) 259 260 def p_decl__machine0(self, p): 261 "decl : MACHINE '(' idents ')' ':' obj_decls '{' decls '}'" 262 p[0] = ast.MachineAST(self, p[3], [], p[7], p[9]) 263 264 def p_decl__machine1(self, p): 265 "decl : MACHINE '(' idents pairs ')' ':' obj_decls '{' decls '}'" 266 p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9]) 267 268 def p_decl__action(self, p): 269 "decl : ACTION '(' ident pairs ')' statements" 270 p[0] = ast.ActionDeclAST(self, p[3], p[4], p[6]) 271 272 def p_decl__in_port(self, p): 273 "decl : IN_PORT '(' ident ',' type ',' var pairs ')' statements" 274 p[0] = ast.InPortDeclAST(self, p[3], p[5], p[7], p[8], p[10]) 275 276 def p_decl__out_port(self, p): 277 "decl : OUT_PORT '(' ident ',' type ',' var pairs ')' SEMI" 278 p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8]) 279 280 def p_decl__trans0(self, p): 281 "decl : TRANS '(' idents ',' idents ',' ident_or_star ')' idents" 282 p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], p[7], p[9]) 283 284 def p_decl__trans1(self, p): 285 "decl : TRANS '(' idents ',' idents ')' idents" 286 p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], None, p[7]) 287 288 def p_decl__trans2(self, p): 289 "decl : TRANS '(' idents ',' idents ',' ident_or_star ')' idents idents" 290 p[0] = ast.TransitionDeclAST(self, p[9], p[3], p[5], p[7], p[10]) 291 292 def p_decl__trans3(self, p): 293 "decl : TRANS '(' idents ',' idents ')' idents idents" 294 p[0] = ast.TransitionDeclAST(self, p[7], p[3], p[5], None, p[8]) 295 296 def p_decl__extern0(self, p): 297 "decl : EXTERN_TYPE '(' type pairs ')' SEMI" 298 p[4]["external"] = "yes" 299 p[0] = ast.TypeDeclAST(self, p[3], p[4], []) 300 301 def p_decl__global(self, p): 302 "decl : GLOBAL '(' type pairs ')' '{' type_members '}'" 303 p[4]["global"] = "yes" 304 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) 305 306 def p_decl__struct(self, p): 307 "decl : STRUCT '(' type pairs ')' '{' type_members '}'" 308 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) 309 310 def p_decl__enum(self, p): 311 "decl : ENUM '(' type pairs ')' '{' type_enums '}'" 312 p[4]["enumeration"] = "yes" 313 p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7]) 314 315 def p_decl__state_decl(self, p): 316 "decl : STATE_DECL '(' type pairs ')' '{' type_states '}'" 317 p[4]["enumeration"] = "yes" 318 p[4]["state_decl"] = "yes" 319 p[0] = ast.StateDeclAST(self, p[3], p[4], p[7]) 320 321 # Type fields 322 def p_obj_decls__list(self, p): 323 "obj_decls : obj_decl obj_decls" 324 p[0] = [ p[1] ] + p[2] 325 326 def p_obj_decls__empty(self, p): 327 "obj_decls : empty" 328 p[0] = [] 329 330 def p_type_members__list(self, p): 331 "type_members : type_member type_members" 332 p[0] = [ p[1] ] + p[2] 333 334 def p_type_members__empty(self, p): 335 "type_members : empty" 336 p[0] = [] 337 338 def p_type_member__0(self, p): 339 """type_member : obj_decl 340 | func_decl 341 | func_def""" 342 p[0] = p[1] 343 344 # Member / Variable declarations 345 def p_decl__obj_decl(self, p): 346 "decl : obj_decl" 347 p[0] = p[1] 348 349 def p_obj_decl__0(self, p): 350 "obj_decl : type ident pairs SEMI" 351 p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3], None, False) 352 353 def p_obj_decl__1(self, p): 354 "obj_decl : type STAR ident pairs SEMI" 355 p[0] = ast.ObjDeclAST(self, p[1], p[3], p[4], None, True) 356 357 def p_obj_decl__2(self, p): 358 "obj_decl : type ident ASSIGN expr SEMI" 359 p[0] = ast.ObjDeclAST(self, p[1], p[2], ast.PairListAST(self), p[4], 360 False) 361 362 def p_obj_decl__3(self, p): 363 "obj_decl : type STAR ident ASSIGN expr SEMI" 364 p[0] = ast.ObjDeclAST(self, p[1], p[3], ast.PairListAST(self), p[5], 365 True) 366 367 # Function definition and declaration 368 def p_decl__func_decl(self, p): 369 "decl : func_decl" 370 p[0] = p[1] 371 372 def p_func_decl__0(self, p): 373 """func_decl : void ident '(' params ')' pairs SEMI 374 | type ident '(' params ')' pairs SEMI""" 375 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None) 376 377 def p_func_decl__1(self, p): 378 """func_decl : void ident '(' types ')' pairs SEMI 379 | type ident '(' types ')' pairs SEMI""" 380 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None) 381 382 def p_decl__func_def(self, p): 383 "decl : func_def" 384 p[0] = p[1] 385 386 def p_func_def__0(self, p): 387 """func_def : void ident '(' params ')' pairs statements 388 | type ident '(' params ')' pairs statements""" 389 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7]) 390 391 # Enum fields 392 def p_type_enums__list(self, p): 393 "type_enums : type_enum type_enums" 394 p[0] = [ p[1] ] + p[2] 395 396 def p_type_enums__empty(self, p): 397 "type_enums : empty" 398 p[0] = [] 399 400 def p_type_enum(self, p): 401 "type_enum : ident pairs SEMI" 402 p[0] = ast.TypeFieldEnumAST(self, p[1], p[2]) 403 404 # States 405 def p_type_states__list(self, p): 406 "type_states : type_state type_states" 407 p[0] = [ p[1] ] + p[2] 408 409 def p_type_states__empty(self, p): 410 "type_states : empty" 411 p[0] = [] 412 413 def p_type_state(self, p): 414 "type_state : ident ',' enumeration pairs SEMI" 415 p[0] = ast.TypeFieldStateAST(self, p[1], p[3], p[4]) 416 417 # Formal Param 418 def p_params__many(self, p): 419 "params : param ',' params" 420 p[0] = [ p[1] ] + p[3] 421 422 def p_params__one(self, p): 423 "params : param" 424 p[0] = [ p[1] ] 425 426 def p_params__none(self, p): 427 "params : empty" 428 p[0] = [] 429 430 def p_param(self, p): 431 "param : type ident" 432 p[0] = ast.FormalParamAST(self, p[1], p[2]) 433 434 def p_param__pointer(self, p): 435 "param : type STAR ident" 436 p[0] = ast.FormalParamAST(self, p[1], p[3], None, True) 437 438 def p_param__pointer_default(self, p): 439 "param : type STAR ident ASSIGN STRING" 440 p[0] = ast.FormalParamAST(self, p[1], p[3], p[5], True) 441 442 def p_param__default_number(self, p): 443 "param : type ident ASSIGN NUMBER" 444 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4]) 445 446 def p_param__default_bool(self, p): 447 "param : type ident ASSIGN LIT_BOOL" 448 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4]) 449 450 def p_param__default_string(self, p): 451 "param : type ident ASSIGN STRING" 452 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4]) 453 454 # Type 455 def p_types__multiple(self, p): 456 "types : type ',' types" 457 p[0] = [ p[1] ] + p[3] 458 459 def p_types__one(self, p): 460 "types : type" 461 p[0] = [ p[1] ] 462 463 def p_types__empty(self, p): 464 "types : empty" 465 p[0] = [] 466 467 def p_typestr__multi(self, p): 468 "typestr : typestr DOUBLE_COLON ident" 469 p[0] = '%s::%s' % (p[1], p[3]) 470 471 def p_typestr__single(self, p): 472 "typestr : ident" 473 p[0] = p[1] 474 475 def p_type__one(self, p): 476 "type : typestr" 477 p[0] = ast.TypeAST(self, p[1]) 478 479 def p_void(self, p): 480 "void : VOID" 481 p[0] = ast.TypeAST(self, p[1]) 482 483 # Idents and lists 484 def p_idents__braced(self, p): 485 "idents : '{' identx '}'" 486 p[0] = p[2] 487 488 def p_idents__bare(self, p): 489 "idents : ident" 490 p[0] = [ p[1] ] 491 492 def p_identx__multiple_1(self, p): 493 """identx : ident SEMI identx 494 | ident ',' identx""" 495 p[0] = [ p[1] ] + p[3] 496 497 def p_identx__multiple_2(self, p): 498 "identx : ident identx" 499 p[0] = [ p[1] ] + p[2] 500 501 def p_identx__single(self, p): 502 "identx : empty" 503 p[0] = [ ] 504 505 def p_ident(self, p): 506 "ident : IDENT" 507 p[0] = p[1] 508 509 def p_ident_or_star(self, p): 510 """ident_or_star : ident 511 | STAR""" 512 p[0] = p[1] 513 514 # Pair and pair lists 515 def p_pairs__list(self, p): 516 "pairs : ',' pairsx" 517 p[0] = p[2] 518 519 def p_pairs__empty(self, p): 520 "pairs : empty" 521 p[0] = ast.PairListAST(self) 522 523 def p_pairsx__many(self, p): 524 "pairsx : pair ',' pairsx" 525 p[0] = p[3] 526 p[0].addPair(p[1]) 527 528 def p_pairsx__one(self, p): 529 "pairsx : pair" 530 p[0] = ast.PairListAST(self) 531 p[0].addPair(p[1]) 532 533 def p_pair__assign(self, p): 534 """pair : ident '=' STRING 535 | ident '=' ident 536 | ident '=' NUMBER""" 537 p[0] = ast.PairAST(self, p[1], p[3]) 538 539 def p_pair__literal(self, p): 540 "pair : STRING" 541 p[0] = ast.PairAST(self, "short", p[1]) 542 543 # Below are the rules for action descriptions 544 def p_statements__inner(self, p): 545 "statements : '{' statements_inner '}'" 546 p[0] = ast.StatementListAST(self, p[2]) 547 548 def p_statements__none(self, p): 549 "statements : '{' '}'" 550 p[0] = ast.StatementListAST(self, []) 551 552 def p_statements_inner__many(self, p): 553 "statements_inner : statement statements_inner" 554 p[0] = [ p[1] ] + p[2] 555 556 def p_statements_inner__one(self, p): 557 "statements_inner : statement" 558 p[0] = [ p[1] ] 559 560 def p_exprs__multiple(self, p): 561 "exprs : expr ',' exprs" 562 p[0] = [ p[1] ] + p[3] 563 564 def p_exprs__one(self, p): 565 "exprs : expr" 566 p[0] = [ p[1] ] 567 568 def p_exprs__empty(self, p): 569 "exprs : empty""" 570 p[0] = [] 571 572 def p_statement__expression(self, p): 573 "statement : expr SEMI" 574 p[0] = ast.ExprStatementAST(self, p[1]) 575 576 def p_statement__assign(self, p): 577 "statement : expr ASSIGN expr SEMI" 578 p[0] = ast.AssignStatementAST(self, p[1], p[3]) 579 580 def p_statement__enqueue(self, p): 581 "statement : ENQUEUE '(' var ',' type ')' statements" 582 p[0] = ast.EnqueueStatementAST(self, p[3], p[5], None, p[7]) 583 584 def p_statement__enqueue_latency(self, p): 585 "statement : ENQUEUE '(' var ',' type ',' expr ')' statements" 586 p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[7], p[9]) 587 588 def p_statement__stall_and_wait(self, p): 589 "statement : STALL_AND_WAIT '(' var ',' var ')' SEMI" 590 p[0] = ast.StallAndWaitStatementAST(self, p[3], p[5]) 591 592 def p_statement__peek(self, p): 593 "statement : PEEK '(' var ',' type pairs ')' statements" 594 p[0] = ast.PeekStatementAST(self, p[3], p[5], p[6], p[8], "peek") 595 596 def p_statement__check_allocate(self, p): 597 "statement : CHECK_ALLOCATE '(' var ')' SEMI" 598 p[0] = ast.CheckAllocateStatementAST(self, p[3]) 599 600 def p_statement__check_stop(self, p): 601 "statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI" 602 p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7]) 603 604 def p_statement__return(self, p): 605 "statement : RETURN expr SEMI" 606 p[0] = ast.ReturnStatementAST(self, p[2]) 607 608 def p_statement__if(self, p): 609 "statement : if_statement" 610 p[0] = p[1] 611 612 def p_if_statement__if(self, p): 613 "if_statement : IF '(' expr ')' statements" 614 p[0] = ast.IfStatementAST(self, p[3], p[5], None) 615 616 def p_if_statement__if_else(self, p): 617 "if_statement : IF '(' expr ')' statements ELSE statements" 618 p[0] = ast.IfStatementAST(self, p[3], p[5], p[7]) 619 620 def p_statement__if_else_if(self, p): 621 "if_statement : IF '(' expr ')' statements ELSE if_statement" 622 p[0] = ast.IfStatementAST(self, p[3], p[5], 623 ast.StatementListAST(self, p[7])) 624 625 def p_expr__static_cast(self, p): 626 "aexpr : STATIC_CAST '(' type ',' expr ')'" 627 p[0] = ast.StaticCastAST(self, p[3], "ref", p[5]) 628 629 def p_expr__static_cast_ptr(self, p): 630 "aexpr : STATIC_CAST '(' type ',' STRING ',' expr ')'" 631 p[0] = ast.StaticCastAST(self, p[3], p[5], p[7]) 632 633 def p_expr__var(self, p): 634 "aexpr : var" 635 p[0] = p[1] 636 637 def p_expr__localvar(self, p): 638 "aexpr : type ident" 639 p[0] = ast.LocalVariableAST(self, p[1], p[2]) 640 641 def p_expr__literal(self, p): 642 "aexpr : literal" 643 p[0] = p[1] 644 645 def p_expr__enumeration(self, p): 646 "aexpr : enumeration" 647 p[0] = p[1] 648 649 def p_expr__func_call(self, p): 650 "aexpr : ident '(' exprs ')'" 651 p[0] = ast.FuncCallExprAST(self, p[1], p[3]) 652 653 def p_expr__new(self, p): 654 "aexpr : NEW type" 655 p[0] = ast.NewExprAST(self, p[2]) 656 657 def p_expr__null(self, p): 658 "aexpr : OOD" 659 p[0] = ast.OodAST(self) 660 661 def p_expr__member(self, p): 662 "aexpr : aexpr DOT ident" 663 p[0] = ast.MemberExprAST(self, p[1], p[3]) 664 665 def p_expr__member_method_call(self, p): 666 "aexpr : aexpr DOT ident '(' exprs ')'" 667 p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5]) 668 669 def p_expr__member_method_call_lookup(self, p): 670 "aexpr : aexpr '[' exprs ']'" 671 p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3]) 672 673 def p_expr__class_method_call(self, p): 674 "aexpr : type DOUBLE_COLON ident '(' exprs ')'" 675 p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5]) 676 677 def p_expr__aexpr(self, p): 678 "expr : aexpr" 679 p[0] = p[1] 680 681 def p_expr__binary_op(self, p): 682 """expr : expr STAR expr 683 | expr SLASH expr 684 | expr PLUS expr 685 | expr DASH expr 686 | expr LT expr 687 | expr GT expr 688 | expr LE expr 689 | expr GE expr 690 | expr EQ expr 691 | expr NE expr 692 | expr AND expr 693 | expr OR expr 694 | expr RIGHTSHIFT expr 695 | expr LEFTSHIFT expr""" 696 p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3]) 697 698 # FIXME - unary not 699 def p_expr__unary_op(self, p): 700 """expr : NOT expr 701 | INCR expr 702 | DECR expr 703 | DASH expr %prec UMINUS""" 704 p[0] = ast.PrefixOperatorExprAST(self, p[1], p[2]) 705 706 def p_expr__parens(self, p): 707 "aexpr : '(' expr ')'" 708 p[0] = p[2] 709 710 def p_expr__is_valid_ptr(self, p): 711 "aexpr : IS_VALID '(' var ')'" 712 p[0] = ast.IsValidPtrExprAST(self, p[3], True) 713 714 def p_expr__is_invalid_ptr(self, p): 715 "aexpr : IS_INVALID '(' var ')'" 716 p[0] = ast.IsValidPtrExprAST(self, p[3], False) 717 718 def p_literal__string(self, p): 719 "literal : STRING" 720 p[0] = ast.LiteralExprAST(self, p[1], "std::string") 721 722 def p_literal__number(self, p): 723 "literal : NUMBER" 724 p[0] = ast.LiteralExprAST(self, p[1], "int") 725 726 def p_literal__float(self, p): 727 "literal : FLOATNUMBER" 728 p[0] = ast.LiteralExprAST(self, p[1], "int") 729 730 def p_literal__bool(self, p): 731 "literal : LIT_BOOL" 732 p[0] = ast.LiteralExprAST(self, p[1], "bool") 733 734 def p_enumeration(self, p): 735 "enumeration : ident ':' ident" 736 p[0] = ast.EnumExprAST(self, ast.TypeAST(self, p[1]), p[3]) 737 738 def p_var(self, p): 739 "var : ident" 740 p[0] = ast.VarExprAST(self, p[1]) 741