def p_factory(p): '''factory : FACTORY ID LBRACE factory_creator factory_receiver RBRACE | FACTORY ID LBRACE factory_creator RBRACE''' if len(p) == 7: p[0] = GenMsgAST.Factory(p[2], p[4], p[5]) p[0].linespan = (p.linespan(1)[0], p.linespan(6)[1]) elif len(p) == 6: p[0] = GenMsgAST.Factory(p[2], p[4]) p[0].linespan = (p.linespan(1)[0], p.linespan(5)[1])
def p_native(p): '''native : NATIVE ID LBRACE native_line_list RBRACE''' # we should reverse the language list # because the parse build it the other way around (recursive way) p[4].reverse() p[0] = GenMsgAST.NativeType(p[2], p[4]) p[0].linespan = (p.linespan(1)[0], p.linespan(5)[1])
def p_message(p): '''message : MESSAGE ID LBRACE RBRACE | MESSAGE ID LBRACE field_list RBRACE | MESSAGE ID COLON MERGE ID LBRACE RBRACE | MESSAGE ID COLON MERGE ID LBRACE field_list RBRACE''' if len(p) == 5: p[0] = GenMsgAST.MessageType(p[2], [], None) elif len(p) == 6: p[4].reverse() p[0] = GenMsgAST.MessageType(p[2], p[4], None) elif len(p) == 8: p[0] = GenMsgAST.MessageType(p[2], [], p[5]) elif len(p) == 9: p[7].reverse() p[0] = GenMsgAST.MessageType(p[2], p[7], p[5]) p[0].linespan = (p.linespan(1)[0], p.linespan(len(p) - 1)[1])
def p_enum(p): '''enum : ENUM ID LBRACE enum_value_list RBRACE''' # we should reverse the enum value list # because the parse build it the other way around (recursive way) p[4].reverse() p[0] = GenMsgAST.EnumType(p[2], p[4]) p[0].linespan = (p.linespan(1)[0], p.linespan(5)[1])
def p_comment_block(p): '''comment_block : COMMENT | COMMENT comment_block''' if len(p) == 2: p[0] = GenMsgAST.CommentBlock(p[1].strip('/'), isAtEOL=False) else: p[0] = p[2] p[0].lines.append(p[1].strip('/'))
def p_eol_comment(p): '''eol_comment : COMMENT | empty''' # we may store the comment text for future use if len(p) > 1 and isinstance(p[1], type('')): p[0] = GenMsgAST.CommentBlock(p[1].strip('/'), isAtEOL=True) p[0].linespan = p.linespan(1) else: p[0] = ''
def p_version(p): '''version : VERSION INTEGER_VALUE PERIOD INTEGER_VALUE''' p[0] = GenMsgAST.Version((p[2], p[4]))
def p_package(p): '''package : PACKAGE package_id''' p[0] = GenMsgAST.Package(p[2]) p[0].linespan = (p.linespan(1)[0], p.linespan(2)[1])
if inputFile != None: mainlogger.info('Parsing message file specifications...') try: msgFile = open(inputFile, 'r') except IOError, e: mainlogger.error('IOError raised: <' + str(e) + '>') mainlogger.error('May be input file <%s> is unreadable or mispelled?' % inputFile) sys.exit() else: mainlogger.error('No input file given!!') sys.exit() lexer.lineno = 1 parser.AST = GenMsgAST.MessageAST(inputFile) parser.parse(msgFile.read(), lexer=lexer, tracking=True) parser.AST.messages.reverse() parser.AST.enums.reverse() parser.AST.natives.reverse() if lexer.syntax: msgFile.close() mainlogger.info('Parse succeeded %s' % parser.AST) mainlogger.info('Checking AST properties....') checker = GenMsgAST.ASTChecker() checker.check(parser.AST) if parser.AST.checked: mainlogger.info('AST properties checked Ok.') else: mainlogger.error('AST has error, generation step may produce invalid files!!!'