parser.py revision 9104
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, verbose=False, traceback=False, **kwargs): 42 self.protocol = None 43 self.traceback = traceback 44 self.verbose = verbose 45 self.symtab = SymbolTable(self) 46 47 try: 48 self.decl_list = self.parse_file(filename, **kwargs) 49 except ParseError, e: 50 if not self.traceback: 51 sys.exit(str(e)) 52 raise 53 54 def currentLocation(self): 55 return util.Location(self.current_source, self.current_line, 56 no_warning=not self.verbose) 57 58 def codeFormatter(self, *args, **kwargs): 59 code = code_formatter(*args, **kwargs) 60 code['protocol'] = self.protocol 61 return code 62 63 def process(self): 64 self.decl_list.findMachines() 65 self.decl_list.generate() 66 67 def writeCodeFiles(self, code_path): 68 self.symtab.writeCodeFiles(code_path) 69 70 def writeHTMLFiles(self, html_path): 71 self.symtab.writeHTMLFiles(html_path) 72 73 def files(self): 74 f = set([ 75 'MachineType.cc', 76 'MachineType.hh', 77 'Types.hh' ]) 78 79 f |= self.decl_list.files() 80 81 return f 82 83 t_ignore = '\t ' 84 85 # C or C++ comment (ignore) 86 def t_c_comment(self, t): 87 r'/\*(.|\n)*?\*/' 88 t.lexer.lineno += t.value.count('\n') 89 90 def t_cpp_comment(self, t): 91 r'//.*' 92 93 # Define a rule so we can track line numbers 94 def t_newline(self, t): 95 r'\n+' 96 t.lexer.lineno += len(t.value) 97 98 reserved = { 99 'protocol' : 'PROTOCOL', 100 'include' : 'INCLUDE', 101 'global' : 'GLOBAL', 102 'machine' : 'MACHINE', 103 'in_port' : 'IN_PORT', 104 'out_port' : 'OUT_PORT', 105 'action' : 'ACTION', 106 'transition' : 'TRANS', 107 'structure' : 'STRUCT', 108 'external_type' : 'EXTERN_TYPE', 109 'enumeration' : 'ENUM', 110 'state_declaration' : 'STATE_DECL', 111 'peek' : 'PEEK', 112 'stall_and_wait' : 'STALL_AND_WAIT', 113 'enqueue' : 'ENQUEUE', 114 'copy_head' : 'COPY_HEAD', 115 'check_allocate' : 'CHECK_ALLOCATE', 116 'check_stop_slots' : 'CHECK_STOP_SLOTS', 117 'static_cast' : 'STATIC_CAST', 118 'if' : 'IF', 119 'is_valid' : 'IS_VALID', 120 'is_invalid' : 'IS_INVALID', 121 'else' : 'ELSE', 122 'return' : 'RETURN', 123 'THIS' : 'THIS', 124 'CHIP' : 'CHIP', 125 'void' : 'VOID', 126 'new' : 'NEW', 127 'OOD' : 'OOD', 128 } 129 130 literals = ':[]{}(),=' 131 132 tokens = [ 'EQ', 'NE', 'LT', 'GT', 'LE', 'GE', 133 'LEFTSHIFT', 'RIGHTSHIFT', 134 'NOT', 'AND', 'OR', 135 'PLUS', 'DASH', 'STAR', 'SLASH', 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 161 precedence = ( 162 ('left', 'AND', 'OR'), 163 ('left', 'EQ', 'NE'), 164 ('left', 'LT', 'GT', 'LE', 'GE'), 165 ('left', 'RIGHTSHIFT', 'LEFTSHIFT'), 166 ('left', 'PLUS', 'DASH'), 167 ('left', 'STAR', 'SLASH'), 168 ('right', 'NOT', 'UMINUS'), 169 ) 170 171 def t_IDENT(self, t): 172 r'[a-zA-Z_][a-zA-Z_0-9]*' 173 if t.value == 'true': 174 t.type = 'LIT_BOOL' 175 t.value = True 176 return t 177 178 if t.value == 'false': 179 t.type = 'LIT_BOOL' 180 t.value = False 181 return t 182 183 # Check for reserved words 184 t.type = self.reserved.get(t.value, 'IDENT') 185 return t 186 187 def t_FLOATNUMBER(self, t): 188 '[0-9]+[.][0-9]+' 189 try: 190 t.value = float(t.value) 191 except ValueError: 192 raise ParseError("Illegal float", t) 193 return t 194 195 def t_NUMBER(self, t): 196 r'[0-9]+' 197 try: 198 t.value = int(t.value) 199 except ValueError: 200 raise ParseError("Illegal number", t) 201 return t 202 203 def t_STRING1(self, t): 204 r'\"[^"\n]*\"' 205 t.type = 'STRING' 206 t.value = t.value[1:-1] 207 return t 208 209 def t_STRING2(self, t): 210 r"\'[^'\n]*\'" 211 t.type = 'STRING' 212 t.value = t.value[1:-1] 213 return t 214 215 def p_file(self, p): 216 "file : decls" 217 p[0] = p[1] 218 219 def p_empty(self, p): 220 "empty :" 221 222 def p_decls(self, p): 223 "decls : declsx" 224 p[0] = ast.DeclListAST(self, p[1]) 225 226 def p_declsx__list(self, p): 227 "declsx : decl declsx" 228 if isinstance(p[1], ast.DeclListAST): 229 decls = p[1].decls 230 elif p[1] is None: 231 decls = [] 232 else: 233 decls = [ p[1] ] 234 p[0] = decls + p[2] 235 236 def p_declsx__none(self, p): 237 "declsx : empty" 238 p[0] = [] 239 240 def p_decl__protocol(self, p): 241 "decl : PROTOCOL STRING SEMI" 242 if self.protocol: 243 msg = "Protocol can only be set once! Error at %s:%s\n" % \ 244 (self.current_source, self.current_line) 245 raise ParseError(msg) 246 self.protocol = p[2] 247 p[0] = None 248 249 def p_decl__include(self, p): 250 "decl : INCLUDE STRING SEMI" 251 dirname = os.path.dirname(self.current_source) 252 filename = os.path.join(dirname, p[2]) 253 p[0] = self.parse_file(filename) 254 255 def p_decl__machine(self, p): 256 "decl : MACHINE '(' ident pairs ')' ':' params '{' decls '}'" 257 p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9]) 258 259 def p_decl__action(self, p): 260 "decl : ACTION '(' ident pairs ')' statements" 261 p[0] = ast.ActionDeclAST(self, p[3], p[4], p[6]) 262 263 def p_decl__in_port(self, p): 264 "decl : IN_PORT '(' ident ',' type ',' var pairs ')' statements" 265 p[0] = ast.InPortDeclAST(self, p[3], p[5], p[7], p[8], p[10]) 266 267 def p_decl__out_port(self, p): 268 "decl : OUT_PORT '(' ident ',' type ',' var pairs ')' SEMI" 269 p[0] = ast.OutPortDeclAST(self, p[3], p[5], p[7], p[8]) 270 271 def p_decl__trans0(self, p): 272 "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents" 273 p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], p[7], p[8], p[10]) 274 275 def p_decl__trans1(self, p): 276 "decl : TRANS '(' idents ',' idents pairs ')' idents" 277 p[0] = ast.TransitionDeclAST(self, [], p[3], p[5], None, p[6], p[8]) 278 279 def p_decl__trans2(self, p): 280 "decl : TRANS '(' idents ',' idents ',' ident pairs ')' idents idents" 281 p[0] = ast.TransitionDeclAST(self, p[10], p[3], p[5], p[7], p[8], p[11]) 282 283 def p_decl__trans3(self, p): 284 "decl : TRANS '(' idents ',' idents pairs ')' idents idents" 285 p[0] = ast.TransitionDeclAST(self, p[8], p[3], p[5], None, p[6], p[9]) 286 287 def p_decl__extern0(self, p): 288 "decl : EXTERN_TYPE '(' type pairs ')' SEMI" 289 p[4]["external"] = "yes" 290 p[0] = ast.TypeDeclAST(self, p[3], p[4], []) 291 292 def p_decl__global(self, p): 293 "decl : GLOBAL '(' type pairs ')' '{' type_members '}'" 294 p[4]["global"] = "yes" 295 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) 296 297 def p_decl__struct(self, p): 298 "decl : STRUCT '(' type pairs ')' '{' type_members '}'" 299 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) 300 301 def p_decl__enum(self, p): 302 "decl : ENUM '(' type pairs ')' '{' type_enums '}'" 303 p[4]["enumeration"] = "yes" 304 p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7]) 305 306 def p_decl__state_decl(self, p): 307 "decl : STATE_DECL '(' type pairs ')' '{' type_states '}'" 308 p[4]["enumeration"] = "yes" 309 p[4]["state_decl"] = "yes" 310 p[0] = ast.StateDeclAST(self, p[3], p[4], p[7]) 311 312 def p_decl__object(self, p): 313 "decl : type ident pairs SEMI" 314 p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3]) 315 316 def p_decl__func_decl(self, p): 317 """decl : void ident '(' params ')' pairs SEMI 318 | type ident '(' params ')' pairs SEMI""" 319 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None) 320 321 def p_decl__func_def(self, p): 322 """decl : void ident '(' params ')' pairs statements 323 | type ident '(' params ')' pairs statements""" 324 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7]) 325 326 # Type fields 327 def p_type_members__list(self, p): 328 "type_members : type_member type_members" 329 p[0] = [ p[1] ] + p[2] 330 331 def p_type_members__empty(self, p): 332 "type_members : empty" 333 p[0] = [] 334 335 def p_type_method__0(self, p): 336 "type_member : type_or_void ident '(' types ')' pairs SEMI" 337 p[0] = ast.TypeFieldMethodAST(self, p[1], p[2], p[4], p[6]) 338 339 def p_type_member__1(self, p): 340 "type_member : type_or_void ident pairs SEMI" 341 p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], p[3], None) 342 343 def p_type_member__2(self, p): 344 "type_member : type_or_void ident ASSIGN expr SEMI" 345 p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], 346 ast.PairListAST(self), p[4]) 347 348 # Enum fields 349 def p_type_enums__list(self, p): 350 "type_enums : type_enum type_enums" 351 p[0] = [ p[1] ] + p[2] 352 353 def p_type_enums__empty(self, p): 354 "type_enums : empty" 355 p[0] = [] 356 357 def p_type_enum(self, p): 358 "type_enum : ident pairs SEMI" 359 p[0] = ast.TypeFieldEnumAST(self, p[1], p[2]) 360 361 # States 362 def p_type_states__list(self, p): 363 "type_states : type_state type_states" 364 p[0] = [ p[1] ] + p[2] 365 366 def p_type_states__empty(self, p): 367 "type_states : empty" 368 p[0] = [] 369 370 def p_type_state(self, p): 371 "type_state : ident ',' enumeration pairs SEMI" 372 p[0] = ast.TypeFieldStateAST(self, p[1], p[3], p[4]) 373 374 # Type 375 def p_types__multiple(self, p): 376 "types : type ',' types" 377 p[0] = [ p[1] ] + p[3] 378 379 def p_types__one(self, p): 380 "types : type" 381 p[0] = [ p[1] ] 382 383 def p_types__empty(self, p): 384 "types : empty" 385 p[0] = [] 386 387 def p_typestr__multi(self, p): 388 "typestr : typestr DOUBLE_COLON ident" 389 p[0] = '%s::%s' % (p[1], p[3]) 390 391 def p_typestr__single(self, p): 392 "typestr : ident" 393 p[0] = p[1] 394 395 def p_type__one(self, p): 396 "type : typestr" 397 p[0] = ast.TypeAST(self, p[1]) 398 399 def p_void(self, p): 400 "void : VOID" 401 p[0] = ast.TypeAST(self, p[1]) 402 403 def p_type_or_void(self, p): 404 """type_or_void : type 405 | void""" 406 p[0] = p[1] 407 408 # Formal Param 409 def p_params__many(self, p): 410 "params : param ',' params" 411 p[0] = [ p[1] ] + p[3] 412 413 def p_params__one(self, p): 414 "params : param" 415 p[0] = [ p[1] ] 416 417 def p_params__none(self, p): 418 "params : empty" 419 p[0] = [] 420 421 def p_param(self, p): 422 "param : type ident" 423 p[0] = ast.FormalParamAST(self, p[1], p[2]) 424 425 def p_param__pointer(self, p): 426 "param : type STAR ident" 427 p[0] = ast.FormalParamAST(self, p[1], p[3], None, True) 428 429 def p_param__pointer_default(self, p): 430 "param : type STAR ident '=' STRING" 431 p[0] = ast.FormalParamAST(self, p[1], p[3], p[5], True) 432 433 def p_param__default_number(self, p): 434 "param : type ident '=' NUMBER" 435 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4]) 436 437 def p_param__default_bool(self, p): 438 "param : type ident '=' LIT_BOOL" 439 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4]) 440 441 def p_param__default_string(self, p): 442 "param : type ident '=' STRING" 443 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4]) 444 445 # Idents and lists 446 def p_idents__braced(self, p): 447 "idents : '{' identx '}'" 448 p[0] = p[2] 449 450 def p_idents__bare(self, p): 451 "idents : ident" 452 p[0] = [ p[1] ] 453 454 def p_identx__multiple_1(self, p): 455 """identx : ident SEMI identx 456 | ident ',' identx""" 457 p[0] = [ p[1] ] + p[3] 458 459 def p_identx__multiple_2(self, p): 460 "identx : ident identx" 461 p[0] = [ p[1] ] + p[2] 462 463 def p_identx__single(self, p): 464 "identx : empty" 465 p[0] = [ ] 466 467 def p_ident(self, p): 468 "ident : IDENT" 469 p[0] = p[1] 470 471 # Pair and pair lists 472 def p_pairs__list(self, p): 473 "pairs : ',' pairsx" 474 p[0] = p[2] 475 476 def p_pairs__empty(self, p): 477 "pairs : empty" 478 p[0] = ast.PairListAST(self) 479 480 def p_pairsx__many(self, p): 481 "pairsx : pair ',' pairsx" 482 p[0] = p[3] 483 p[0].addPair(p[1]) 484 485 def p_pairsx__one(self, p): 486 "pairsx : pair" 487 p[0] = ast.PairListAST(self) 488 p[0].addPair(p[1]) 489 490 def p_pair__assign(self, p): 491 """pair : ident '=' STRING 492 | ident '=' ident 493 | ident '=' NUMBER""" 494 p[0] = ast.PairAST(self, p[1], p[3]) 495 496 def p_pair__literal(self, p): 497 "pair : STRING" 498 p[0] = ast.PairAST(self, "short", p[1]) 499 500 # Below are the rules for action descriptions 501 def p_statements__inner(self, p): 502 "statements : '{' statements_inner '}'" 503 p[0] = ast.StatementListAST(self, p[2]) 504 505 def p_statements__none(self, p): 506 "statements : '{' '}'" 507 p[0] = ast.StatementListAST(self, []) 508 509 def p_statements_inner__many(self, p): 510 "statements_inner : statement statements_inner" 511 p[0] = [ p[1] ] + p[2] 512 513 def p_statements_inner__one(self, p): 514 "statements_inner : statement" 515 p[0] = [ p[1] ] 516 517 def p_exprs__multiple(self, p): 518 "exprs : expr ',' exprs" 519 p[0] = [ p[1] ] + p[3] 520 521 def p_exprs__one(self, p): 522 "exprs : expr" 523 p[0] = [ p[1] ] 524 525 def p_exprs__empty(self, p): 526 "exprs : empty""" 527 p[0] = [] 528 529 def p_statement__expression(self, p): 530 "statement : expr SEMI" 531 p[0] = ast.ExprStatementAST(self, p[1]) 532 533 def p_statement__assign(self, p): 534 "statement : expr ASSIGN expr SEMI" 535 p[0] = ast.AssignStatementAST(self, p[1], p[3]) 536 537 def p_statement__enqueue(self, p): 538 "statement : ENQUEUE '(' var ',' type pairs ')' statements" 539 p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[6], p[8]) 540 541 def p_statement__stall_and_wait(self, p): 542 "statement : STALL_AND_WAIT '(' var ',' var ')' SEMI" 543 p[0] = ast.StallAndWaitStatementAST(self, p[3], p[5]) 544 545 def p_statement__peek(self, p): 546 "statement : PEEK '(' var ',' type pairs ')' statements" 547 p[0] = ast.PeekStatementAST(self, p[3], p[5], p[6], p[8], "peek") 548 549 def p_statement__copy_head(self, p): 550 "statement : COPY_HEAD '(' var ',' var pairs ')' SEMI" 551 p[0] = ast.CopyHeadStatementAST(self, p[3], p[5], p[6]) 552 553 def p_statement__check_allocate(self, p): 554 "statement : CHECK_ALLOCATE '(' var ')' SEMI" 555 p[0] = ast.CheckAllocateStatementAST(self, p[3]) 556 557 def p_statement__check_stop(self, p): 558 "statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI" 559 p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7]) 560 561 def p_statement__static_cast(self, p): 562 "aexpr : STATIC_CAST '(' type ',' expr ')'" 563 p[0] = ast.StaticCastAST(self, p[3], "ref", p[5]) 564 565 def p_statement__static_cast_ptr(self, p): 566 "aexpr : STATIC_CAST '(' type ',' STRING ',' expr ')'" 567 p[0] = ast.StaticCastAST(self, p[3], p[5], p[7]) 568 569 def p_statement__return(self, p): 570 "statement : RETURN expr SEMI" 571 p[0] = ast.ReturnStatementAST(self, p[2]) 572 573 def p_statement__if(self, p): 574 "statement : if_statement" 575 p[0] = p[1] 576 577 def p_if_statement__if(self, p): 578 "if_statement : IF '(' expr ')' statements" 579 p[0] = ast.IfStatementAST(self, p[3], p[5], None) 580 581 def p_if_statement__if_else(self, p): 582 "if_statement : IF '(' expr ')' statements ELSE statements" 583 p[0] = ast.IfStatementAST(self, p[3], p[5], p[7]) 584 585 def p_statement__if_else_if(self, p): 586 "if_statement : IF '(' expr ')' statements ELSE if_statement" 587 p[0] = ast.IfStatementAST(self, p[3], p[5], 588 ast.StatementListAST(self, p[7])) 589 590 def p_expr__var(self, p): 591 "aexpr : var" 592 p[0] = p[1] 593 594 def p_expr__localvar(self, p): 595 "aexpr : type ident" 596 p[0] = ast.LocalVariableAST(self, p[1], p[2]) 597 598 def p_expr__literal(self, p): 599 "aexpr : literal" 600 p[0] = p[1] 601 602 def p_expr__enumeration(self, p): 603 "aexpr : enumeration" 604 p[0] = p[1] 605 606 def p_expr__func_call(self, p): 607 "aexpr : ident '(' exprs ')'" 608 p[0] = ast.FuncCallExprAST(self, p[1], p[3]) 609 610 def p_expr__new(self, p): 611 "aexpr : NEW type" 612 p[0] = ast.NewExprAST(self, p[2]) 613 614 def p_expr__null(self, p): 615 "aexpr : OOD" 616 p[0] = ast.OodAST(self) 617 618 # globally access a local chip component and call a method 619 def p_expr__local_chip_method(self, p): 620 "aexpr : THIS DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'" 621 p[0] = ast.LocalChipMethodAST(self, p[3], p[5], p[8], p[10], p[12]) 622 623 # globally access a local chip component and access a data member 624 def p_expr__local_chip_member(self, p): 625 "aexpr : THIS DOT var '[' expr ']' DOT var DOT field" 626 p[0] = ast.LocalChipMemberAST(self, p[3], p[5], p[8], p[10]) 627 628 # globally access a specified chip component and call a method 629 def p_expr__specified_chip_method(self, p): 630 "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'" 631 p[0] = ast.SpecifiedChipMethodAST(self, p[3], p[6], p[8], p[11], p[13], 632 p[15]) 633 634 # globally access a specified chip component and access a data member 635 def p_expr__specified_chip_member(self, p): 636 "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field" 637 p[0] = ast.SpecifiedChipMemberAST(self, p[3], p[6], p[8], p[11], p[13]) 638 639 def p_expr__member(self, p): 640 "aexpr : aexpr DOT ident" 641 p[0] = ast.MemberExprAST(self, p[1], p[3]) 642 643 def p_expr__member_method_call(self, p): 644 "aexpr : aexpr DOT ident '(' exprs ')'" 645 p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5]) 646 647 def p_expr__member_method_call_lookup(self, p): 648 "aexpr : aexpr '[' exprs ']'" 649 p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3]) 650 651 def p_expr__class_method_call(self, p): 652 "aexpr : type DOUBLE_COLON ident '(' exprs ')'" 653 p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5]) 654 655 def p_expr__aexpr(self, p): 656 "expr : aexpr" 657 p[0] = p[1] 658 659 def p_expr__binary_op(self, p): 660 """expr : expr STAR expr 661 | expr SLASH expr 662 | expr PLUS expr 663 | expr DASH expr 664 | expr LT expr 665 | expr GT expr 666 | expr LE expr 667 | expr GE expr 668 | expr EQ expr 669 | expr NE expr 670 | expr AND expr 671 | expr OR expr 672 | expr RIGHTSHIFT expr 673 | expr LEFTSHIFT expr""" 674 p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3]) 675 676 # FIXME - unary not 677 def p_expr__unary_op(self, p): 678 """expr : NOT expr 679 | DASH expr %prec UMINUS""" 680 p[0] = PrefixOperatorExpr(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]) 717 718 def p_field(self, p): 719 "field : ident" 720 p[0] = p[1] 721