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