parser.py revision 6907:b05de761960e
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.grammar import Grammar, TokenError, ParseError 34 35import slicc.ast as ast 36import slicc.util as util 37from slicc.symbols import SymbolTable 38 39def read_slicc(sources): 40 if not isinstance(sources, (list,tuple)): 41 sources = [ sources ] 42 43 for source in sources: 44 for sm_file in file(source, "r"): 45 sm_file = sm_file.strip() 46 if not sm_file: 47 continue 48 if sm_file.startswith("#"): 49 continue 50 yield sm_file 51 52class SLICC(Grammar): 53 def __init__(self, **kwargs): 54 super(SLICC, self).__init__(**kwargs) 55 self.decl_list_vec = [] 56 self.current_file = None 57 self.symtab = SymbolTable() 58 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] 691