parser.py revision 8454:fad37c6670a6
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__extern0(self, p): 280 "decl : EXTERN_TYPE '(' type pairs ')' SEMI" 281 p[4]["external"] = "yes" 282 p[0] = ast.TypeDeclAST(self, p[3], p[4], []) 283 284 def p_decl__global(self, p): 285 "decl : GLOBAL '(' type pairs ')' '{' type_members '}'" 286 p[4]["global"] = "yes" 287 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) 288 289 def p_decl__struct(self, p): 290 "decl : STRUCT '(' type pairs ')' '{' type_members '}'" 291 p[0] = ast.TypeDeclAST(self, p[3], p[4], p[7]) 292 293 def p_decl__enum(self, p): 294 "decl : ENUM '(' type pairs ')' '{' type_enums '}'" 295 p[4]["enumeration"] = "yes" 296 p[0] = ast.EnumDeclAST(self, p[3], p[4], p[7]) 297 298 def p_decl__state_decl(self, p): 299 "decl : STATE_DECL '(' type pairs ')' '{' type_states '}'" 300 p[4]["enumeration"] = "yes" 301 p[4]["state_decl"] = "yes" 302 p[0] = ast.StateDeclAST(self, p[3], p[4], p[7]) 303 304 def p_decl__object(self, p): 305 "decl : type ident pairs SEMI" 306 p[0] = ast.ObjDeclAST(self, p[1], p[2], p[3]) 307 308 def p_decl__func_decl(self, p): 309 """decl : void ident '(' params ')' pairs SEMI 310 | type ident '(' params ')' pairs SEMI""" 311 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], None) 312 313 def p_decl__func_def(self, p): 314 """decl : void ident '(' params ')' pairs statements 315 | type ident '(' params ')' pairs statements""" 316 p[0] = ast.FuncDeclAST(self, p[1], p[2], p[4], p[6], p[7]) 317 318 # Type fields 319 def p_type_members__list(self, p): 320 "type_members : type_member type_members" 321 p[0] = [ p[1] ] + p[2] 322 323 def p_type_members__empty(self, p): 324 "type_members : empty" 325 p[0] = [] 326 327 def p_type_method__0(self, p): 328 "type_member : type_or_void ident '(' types ')' pairs SEMI" 329 p[0] = ast.TypeFieldMethodAST(self, p[1], p[2], p[4], p[6]) 330 331 def p_type_member__1(self, p): 332 "type_member : type_or_void ident pairs SEMI" 333 p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], p[3], None) 334 335 def p_type_member__2(self, p): 336 "type_member : type_or_void ident ASSIGN expr SEMI" 337 p[0] = ast.TypeFieldMemberAST(self, p[1], p[2], 338 ast.PairListAST(self), p[4]) 339 340 # Enum fields 341 def p_type_enums__list(self, p): 342 "type_enums : type_enum type_enums" 343 p[0] = [ p[1] ] + p[2] 344 345 def p_type_enums__empty(self, p): 346 "type_enums : empty" 347 p[0] = [] 348 349 def p_type_enum(self, p): 350 "type_enum : ident pairs SEMI" 351 p[0] = ast.TypeFieldEnumAST(self, p[1], p[2]) 352 353 # States 354 def p_type_states__list(self, p): 355 "type_states : type_state type_states" 356 p[0] = [ p[1] ] + p[2] 357 358 def p_type_states__empty(self, p): 359 "type_states : empty" 360 p[0] = [] 361 362 def p_type_state(self, p): 363 "type_state : ident ',' enumeration pairs SEMI" 364 p[0] = ast.TypeFieldStateAST(self, p[1], p[3], p[4]) 365 366 # Type 367 def p_types__multiple(self, p): 368 "types : type ',' types" 369 p[0] = [ p[1] ] + p[3] 370 371 def p_types__one(self, p): 372 "types : type" 373 p[0] = [ p[1] ] 374 375 def p_types__empty(self, p): 376 "types : empty" 377 p[0] = [] 378 379 def p_typestr__multi(self, p): 380 "typestr : typestr DOUBLE_COLON ident" 381 p[0] = '%s::%s' % (p[1], p[3]) 382 383 def p_typestr__single(self, p): 384 "typestr : ident" 385 p[0] = p[1] 386 387 def p_type__one(self, p): 388 "type : typestr" 389 p[0] = ast.TypeAST(self, p[1]) 390 391 def p_void(self, p): 392 "void : VOID" 393 p[0] = ast.TypeAST(self, p[1]) 394 395 def p_type_or_void(self, p): 396 """type_or_void : type 397 | void""" 398 p[0] = p[1] 399 400 # Formal Param 401 def p_params__many(self, p): 402 "params : param ',' params" 403 p[0] = [ p[1] ] + p[3] 404 405 def p_params__one(self, p): 406 "params : param" 407 p[0] = [ p[1] ] 408 409 def p_params__none(self, p): 410 "params : empty" 411 p[0] = [] 412 413 def p_param(self, p): 414 "param : type ident" 415 p[0] = ast.FormalParamAST(self, p[1], p[2]) 416 417 def p_param__pointer(self, p): 418 "param : type STAR ident" 419 p[0] = ast.FormalParamAST(self, p[1], p[3], None, True) 420 421 def p_param__pointer_default(self, p): 422 "param : type STAR ident '=' STRING" 423 p[0] = ast.FormalParamAST(self, p[1], p[3], p[5], True) 424 425 def p_param__default_number(self, p): 426 "param : type ident '=' NUMBER" 427 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4]) 428 429 def p_param__default_bool(self, p): 430 "param : type ident '=' LIT_BOOL" 431 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4]) 432 433 def p_param__default_string(self, p): 434 "param : type ident '=' STRING" 435 p[0] = ast.FormalParamAST(self, p[1], p[2], p[4]) 436 437 # Idents and lists 438 def p_idents__braced(self, p): 439 "idents : '{' identx '}'" 440 p[0] = p[2] 441 442 def p_idents__bare(self, p): 443 "idents : ident" 444 p[0] = [ p[1] ] 445 446 def p_identx__multiple_1(self, p): 447 """identx : ident SEMI identx 448 | ident ',' identx""" 449 p[0] = [ p[1] ] + p[3] 450 451 def p_identx__multiple_2(self, p): 452 "identx : ident identx" 453 p[0] = [ p[1] ] + p[2] 454 455 def p_identx__single(self, p): 456 "identx : empty" 457 p[0] = [ ] 458 459 def p_ident(self, p): 460 "ident : IDENT" 461 p[0] = p[1] 462 463 # Pair and pair lists 464 def p_pairs__list(self, p): 465 "pairs : ',' pairsx" 466 p[0] = p[2] 467 468 def p_pairs__empty(self, p): 469 "pairs : empty" 470 p[0] = ast.PairListAST(self) 471 472 def p_pairsx__many(self, p): 473 "pairsx : pair ',' pairsx" 474 p[0] = p[3] 475 p[0].addPair(p[1]) 476 477 def p_pairsx__one(self, p): 478 "pairsx : pair" 479 p[0] = ast.PairListAST(self) 480 p[0].addPair(p[1]) 481 482 def p_pair__assign(self, p): 483 """pair : ident '=' STRING 484 | ident '=' ident 485 | ident '=' NUMBER""" 486 p[0] = ast.PairAST(self, p[1], p[3]) 487 488 def p_pair__literal(self, p): 489 "pair : STRING" 490 p[0] = ast.PairAST(self, "short", p[1]) 491 492 # Below are the rules for action descriptions 493 def p_statements__inner(self, p): 494 "statements : '{' statements_inner '}'" 495 p[0] = ast.StatementListAST(self, p[2]) 496 497 def p_statements__none(self, p): 498 "statements : '{' '}'" 499 p[0] = ast.StatementListAST(self, []) 500 501 def p_statements_inner__many(self, p): 502 "statements_inner : statement statements_inner" 503 p[0] = [ p[1] ] + p[2] 504 505 def p_statements_inner__one(self, p): 506 "statements_inner : statement" 507 p[0] = [ p[1] ] 508 509 def p_exprs__multiple(self, p): 510 "exprs : expr ',' exprs" 511 p[0] = [ p[1] ] + p[3] 512 513 def p_exprs__one(self, p): 514 "exprs : expr" 515 p[0] = [ p[1] ] 516 517 def p_exprs__empty(self, p): 518 "exprs : empty""" 519 p[0] = [] 520 521 def p_statement__expression(self, p): 522 "statement : expr SEMI" 523 p[0] = ast.ExprStatementAST(self, p[1]) 524 525 def p_statement__assign(self, p): 526 "statement : expr ASSIGN expr SEMI" 527 p[0] = ast.AssignStatementAST(self, p[1], p[3]) 528 529 def p_statement__enqueue(self, p): 530 "statement : ENQUEUE '(' var ',' type pairs ')' statements" 531 p[0] = ast.EnqueueStatementAST(self, p[3], p[5], p[6], p[8]) 532 533 def p_statement__stall_and_wait(self, p): 534 "statement : STALL_AND_WAIT '(' var ',' var ')' SEMI" 535 p[0] = ast.StallAndWaitStatementAST(self, p[3], p[5]) 536 537 def p_statement__peek(self, p): 538 "statement : PEEK '(' var ',' type pairs ')' statements" 539 p[0] = ast.PeekStatementAST(self, p[3], p[5], p[6], p[8], "peek") 540 541 def p_statement__copy_head(self, p): 542 "statement : COPY_HEAD '(' var ',' var pairs ')' SEMI" 543 p[0] = ast.CopyHeadStatementAST(self, p[3], p[5], p[6]) 544 545 def p_statement__check_allocate(self, p): 546 "statement : CHECK_ALLOCATE '(' var ')' SEMI" 547 p[0] = ast.CheckAllocateStatementAST(self, p[3]) 548 549 def p_statement__check_stop(self, p): 550 "statement : CHECK_STOP_SLOTS '(' var ',' STRING ',' STRING ')' SEMI" 551 p[0] = ast.CheckStopStatementAST(self, p[3], p[5], p[7]) 552 553 def p_statement__static_cast(self, p): 554 "aexpr : STATIC_CAST '(' type ',' expr ')'" 555 p[0] = ast.StaticCastAST(self, p[3], "ref", p[5]) 556 557 def p_statement__static_cast_ptr(self, p): 558 "aexpr : STATIC_CAST '(' type ',' STRING ',' expr ')'" 559 p[0] = ast.StaticCastAST(self, p[3], p[5], p[7]) 560 561 def p_statement__return(self, p): 562 "statement : RETURN expr SEMI" 563 p[0] = ast.ReturnStatementAST(self, p[2]) 564 565 def p_statement__if(self, p): 566 "statement : if_statement" 567 p[0] = p[1] 568 569 def p_if_statement__if(self, p): 570 "if_statement : IF '(' expr ')' statements" 571 p[0] = ast.IfStatementAST(self, p[3], p[5], None) 572 573 def p_if_statement__if_else(self, p): 574 "if_statement : IF '(' expr ')' statements ELSE statements" 575 p[0] = ast.IfStatementAST(self, p[3], p[5], p[7]) 576 577 def p_statement__if_else_if(self, p): 578 "if_statement : IF '(' expr ')' statements ELSE if_statement" 579 p[0] = ast.IfStatementAST(self, p[3], p[5], 580 ast.StatementListAST(self, p[7])) 581 582 def p_expr__var(self, p): 583 "aexpr : var" 584 p[0] = p[1] 585 586 def p_expr__localvar(self, p): 587 "aexpr : type ident" 588 p[0] = ast.LocalVariableAST(self, p[1], p[2]) 589 590 def p_expr__literal(self, p): 591 "aexpr : literal" 592 p[0] = p[1] 593 594 def p_expr__enumeration(self, p): 595 "aexpr : enumeration" 596 p[0] = p[1] 597 598 def p_expr__func_call(self, p): 599 "aexpr : ident '(' exprs ')'" 600 p[0] = ast.FuncCallExprAST(self, p[1], p[3]) 601 602 def p_expr__new(self, p): 603 "aexpr : NEW type" 604 p[0] = ast.NewExprAST(self, p[2]) 605 606 def p_expr__null(self, p): 607 "aexpr : OOD" 608 p[0] = ast.OodAST(self) 609 610 # globally access a local chip component and call a method 611 def p_expr__local_chip_method(self, p): 612 "aexpr : THIS DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'" 613 p[0] = ast.LocalChipMethodAST(self, p[3], p[5], p[8], p[10], p[12]) 614 615 # globally access a local chip component and access a data member 616 def p_expr__local_chip_member(self, p): 617 "aexpr : THIS DOT var '[' expr ']' DOT var DOT field" 618 p[0] = ast.LocalChipMemberAST(self, p[3], p[5], p[8], p[10]) 619 620 # globally access a specified chip component and call a method 621 def p_expr__specified_chip_method(self, p): 622 "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT ident '(' exprs ')'" 623 p[0] = ast.SpecifiedChipMethodAST(self, p[3], p[6], p[8], p[11], p[13], 624 p[15]) 625 626 # globally access a specified chip component and access a data member 627 def p_expr__specified_chip_member(self, p): 628 "aexpr : CHIP '[' expr ']' DOT var '[' expr ']' DOT var DOT field" 629 p[0] = ast.SpecifiedChipMemberAST(self, p[3], p[6], p[8], p[11], p[13]) 630 631 def p_expr__member(self, p): 632 "aexpr : aexpr DOT ident" 633 p[0] = ast.MemberExprAST(self, p[1], p[3]) 634 635 def p_expr__member_method_call(self, p): 636 "aexpr : aexpr DOT ident '(' exprs ')'" 637 p[0] = ast.MemberMethodCallExprAST(self, p[1], p[3], p[5]) 638 639 def p_expr__member_method_call_lookup(self, p): 640 "aexpr : aexpr '[' exprs ']'" 641 p[0] = ast.MemberMethodCallExprAST(self, p[1], "lookup", p[3]) 642 643 def p_expr__class_method_call(self, p): 644 "aexpr : type DOUBLE_COLON ident '(' exprs ')'" 645 p[0] = ast.ClassMethodCallExprAST(self, p[1], p[3], p[5]) 646 647 def p_expr__aexpr(self, p): 648 "expr : aexpr" 649 p[0] = p[1] 650 651 def p_expr__binary_op(self, p): 652 """expr : expr STAR expr 653 | expr SLASH expr 654 | expr PLUS expr 655 | expr DASH expr 656 | expr LT expr 657 | expr GT expr 658 | expr LE expr 659 | expr GE expr 660 | expr EQ expr 661 | expr NE expr 662 | expr AND expr 663 | expr OR expr 664 | expr RIGHTSHIFT expr 665 | expr LEFTSHIFT expr""" 666 p[0] = ast.InfixOperatorExprAST(self, p[1], p[2], p[3]) 667 668 # FIXME - unary not 669 def p_expr__unary_op(self, p): 670 """expr : NOT expr 671 | DASH expr %prec UMINUS""" 672 p[0] = PrefixOperatorExpr(p[1], p[2]) 673 674 def p_expr__parens(self, p): 675 "aexpr : '(' expr ')'" 676 p[0] = p[2] 677 678 def p_expr__is_valid_ptr(self, p): 679 "aexpr : IS_VALID '(' var ')'" 680 p[0] = ast.IsValidPtrExprAST(self, p[3], True) 681 682 def p_expr__is_invalid_ptr(self, p): 683 "aexpr : IS_INVALID '(' var ')'" 684 p[0] = ast.IsValidPtrExprAST(self, p[3], False) 685 686 def p_literal__string(self, p): 687 "literal : STRING" 688 p[0] = ast.LiteralExprAST(self, p[1], "std::string") 689 690 def p_literal__number(self, p): 691 "literal : NUMBER" 692 p[0] = ast.LiteralExprAST(self, p[1], "int") 693 694 def p_literal__float(self, p): 695 "literal : FLOATNUMBER" 696 p[0] = ast.LiteralExprAST(self, p[1], "int") 697 698 def p_literal__bool(self, p): 699 "literal : LIT_BOOL" 700 p[0] = ast.LiteralExprAST(self, p[1], "bool") 701 702 def p_enumeration(self, p): 703 "enumeration : ident ':' ident" 704 p[0] = ast.EnumExprAST(self, ast.TypeAST(self, p[1]), p[3]) 705 706 def p_var(self, p): 707 "var : ident" 708 p[0] = ast.VarExprAST(self, p[1]) 709 710 def p_field(self, p): 711 "field : ident" 712 p[0] = p[1] 713