"u16": "uint16_t",
"u32": "uint32_t",
"u64": "uint64_t",
- "float": "double"
+ "float": "float",
+ "double": "double"
}
CPP_CONTAINER_MAP = {
}
def typeToCTypeDeclaration(ttype):
+ """ Converts the thrift IDL type to the corresponding C/C++ type. Note that if ttype is FieldType, this function c
+converts to type declaration followed by field name, i.e. \"string string_thing\""""
if isinstance(ttype, PrimitiveType):
return CPP_PRIMITIVE_MAP[ttype.name]
return ttype.name;
elif isinstance(ttype, Function):
- return typeToCTypeDeclaration(ttype.returnType())+ " "+ttype.name+"("+string.join([typeToCTypeDeclaration(arg) for arg in ttype.args()], ", ")+")"
+ result = typeToCTypeDeclaration(ttype.returnType())+ " "+ttype.name+"("+string.join([typeToCTypeDeclaration(arg) for arg in ttype.args()], ", ")+")"
+ if len(ttype.exceptions()):
+ result+= " throw("+string.join([typeToCTypeDeclaration(exceptions.type) for exceptions in ttype.exceptions()], ", ")+")"
+ return result
elif isinstance(ttype, Field):
return typeToCTypeDeclaration(ttype.type)+ " "+ttype.name
raise Exception, "Unknown type "+str(ttype)
def toTypeDefDefinition(typedef):
+ """ Converts a thrift typedef to a C/C++ typedef """
return "typedef "+typeToCTypeDeclaration(typedef.definitionType)+" "+typedef.name+";"
def toEnumDefinition(enum):
+ """ Converts a thrift enum to a C/C++ enum """
result = "enum "+enum.name+" {\n"
return result
-
def toStructDefinition(struct):
+ """Converts a thrift struct to a C/C++ struct"""
result = "struct "+struct.name+" {\n"
TypedefType : toTypeDefDefinition,
EnumType : toEnumDefinition,
StructType : toStructDefinition,
+ ExceptionType : toStructDefinition,
Service : None
}
def toDefinitions(definitions):
+ """Converts an arbitrafy thrift grammatical unit definition to the corresponding C/C++ definition"""
result = ""
""")
def toServiceInterfaceDeclaration(service, debugp=None):
+ """Converts a thrift service definition into a C++ abstract base class"""
functionDeclarations = string.join([CPP_INTERFACE_FUNCTION_DECLARATION.substitute(service=service.name, functionDeclaration=typeToCTypeDeclaration(function)) for function in service.functionList], "")
U32_TYPE : CPP_PROTOCOL_NS+"::T_U32",
U64_TYPE : CPP_PROTOCOL_NS+"::T_U64",
FLOAT_TYPE : CPP_PROTOCOL_NS+"::T_FLOAT",
+ DOUBLE_TYPE : CPP_PROTOCOL_NS+"::T_DOUBLE",
StructType : CPP_PROTOCOL_NS+"::T_STRUCT",
+ ExceptionType : CPP_PROTOCOL_NS+"::T_STRUCT",
ListType : CPP_PROTOCOL_NS+"::T_LIST",
MapType : CPP_PROTOCOL_NS+"::T_MAP",
SetType : CPP_PROTOCOL_NS+"::T_SET"
_iprot->readMessageEnd(itrans);
- ${returnValueDeclaration};
-
- ${functionCall};
-
${resultStructDeclaration};
- ${returnToResult};
+ ${functionCall};
_oprot->writeMessageBegin(otrans, \"${function}\", """+CPP_PROTOCOL_REPLY+""", seqid);
""")
def toWireType(ttype):
+ """Converts a thrift type to the corresponding wire type. This differs from typeToCTypeDeclaration in that it reduces typedefs
+to their canonical form and converts enums to signedf 32 bit integers"""
if isinstance(ttype, PrimitiveType):
return CPP_TTYPE_MAP[ttype]
""")
def toServerDeclaration(service, debugp=None):
+ """Converts a thrift service definition to the Server skeleton class declaration."""
functionDeclarations = string.join([CPP_SERVER_FUNCTION_DECLARATION.substitute(function=function.name) for function in service.functionList], "")
CPP_CLIENT_FUNCTION_DEFINITION = Template("""
-${returnDeclaration} ${service}Client::${function}(${argsDeclaration}) {
+${returnDeclaration} ${service}Client::${function}(${argsDeclaration}) ${exceptionDeclaration} {
uint32_t xfer = 0;
std::string name;
_iprot->readMessageEnd(_itrans);
if(__result.__isset.success) {
- ${success};
- } else {
- throw """+CPP_EXCEPTION+"""(\"${function} failed\");
+ ${success}
+ } ${error} else {
+ throw """+CPP_EXCEPTION+"""(\"${function} failed: unknown result");
}
}
""")
};""")
def toServerFunctionDefinition(servicePrefix, function, debugp=None):
+ """Converts a thrift service method declaration into a server method-call processoror function"""
result = ""
argsStructDeclaration = typeToCTypeDeclaration(function.argsStruct)+" __args"
resultStructWriter = toWriterCall("__result", function.resultStruct, "_oprot")
+
+
if function.returnType() != VOID_TYPE:
- returnValueDeclaration = typeToCTypeDeclaration(toCanonicalType(function.returnType()))+" __returnValue"
- functionCall = "__returnValue = "
- returnToResult = "__result.success = __returnValue"
+ functionCallPrefix= "__result.success = "
+ functionCallSuffix = "__result.__isset.success = true;"
else:
- returnValueDeclaration = ""
- functionCall = ""
- returnToResult = ""
+ functionCallPrefix = ""
+ functionCallSuffix = ""
+
+ functionCall= function.name+"("+string.join(["__args."+arg.name for arg in function.args()], ", ")+");"
+
+ exceptions = function.exceptions()
- functionCall+= function.name+"("+string.join(["__args."+arg.name for arg in function.args()], ", ")+")"
+ if len(exceptions) > 0:
+ functionCallPrefix= "try {"+functionCallPrefix
+
+ functionCallSuffix = functionCallSuffix+"} "+string.join(["catch("+typeToCTypeDeclaration(exceptions[ix].type)+"& e"+str(ix)+") {__result."+exceptions[ix].name+" = e"+str(ix)+"; __result.__isset."+exceptions[ix].name+" = true;}" for ix in range(len(exceptions))], "")
+
+ functionCall = functionCallPrefix+functionCall+functionCallSuffix
result+= CPP_SERVER_FUNCTION_DEFINITION.substitute(service=servicePrefix, function=function.name,
argsStructDeclaration=argsStructDeclaration,
argsStructReader=argsStructReader,
functionCall=functionCall,
- returnToResult=returnToResult,
resultStructDeclaration=resultStructDeclaration,
- resultStructWriter=resultStructWriter,
- returnValueDeclaration=returnValueDeclaration)
-
-
-
+ resultStructWriter=resultStructWriter)
return result
def toServerServiceDefinition(service, debugp=None):
+ """Converts a thrift service definiton to a server skeleton implementation"""
result = ""
return CPP_CLIENT_DECLARATION.substitute(service=service.name, functionDeclarations=functionDeclarations)+"\n"
def toClientFunctionDefinition(servicePrefix, function, debugp=None):
+ """Converts a thrift service method declaration to a client stub implementation"""
returnDeclaration = typeToCTypeDeclaration(function.returnType())
argsDeclaration = string.join([typeToCTypeDeclaration(function.args()[ix].type)+" __arg"+str(ix) for ix in range(len(function.args()))], ", ")
+ exceptionDeclaration = string.join([typeToCTypeDeclaration(exception.type) for exception in function.exceptions()], ", ")
+
+ if len(exceptionDeclaration)> 0:
+ exceptionDeclaration = "throw("+exceptionDeclaration+")"
+
argsStructDeclaration = typeToCTypeDeclaration(function.argsStruct)+" __args"
argsStructWriter = toWriterCall("__args", function.argsStruct, "_oprot", "_otrans")
success = "return __result.success;"
else:
success = ""
+
+ exceptions = function.exceptions()
+
+ if len(exceptions) > 0:
+ error = "else if "+string.join(["(__result.__isset."+exception.name+") { throw __result."+exception.name+";}" for exception in exceptions], "else if")
+ else:
+ error = ""
return CPP_CLIENT_FUNCTION_DEFINITION.substitute(service=servicePrefix,
function=function.name,
returnDeclaration=returnDeclaration,
argsDeclaration=argsDeclaration,
+ exceptionDeclaration=exceptionDeclaration,
argsStructDeclaration=argsStructDeclaration,
argsStructWriter=argsStructWriter,
argsToStruct=argsToStruct,
resultStructDeclaration=resultStructDeclaration,
resultStructReader=resultStructReader,
- success=success)
+ success=success,
+ error=error)
def toClientServiceDefinition(service, debugp=None):
+ """Converts a thrift service definition to a client stub implementation"""
result = ""
return result
def toClientDefinition(program, debugp=None):
+ """Converts all services in a thrift program to client stub implementations"""
return string.join([toClientServiceDefinition(service) for service in program.serviceMap.values()], "\n")
def toServiceDeclaration(service, debugp=None):
+ """Converts all services in a thrift program to service interface or abstract base class declarations"""
+
return toServiceInterfaceDeclaration(service, debugp) + toServerDeclaration(service, debugp) + toClientDeclaration(service, debugp)
def toGenDir(filename, suffix="cpp-gen", debugp=None):
+ """creates a generated-code subdirectory for C++ code based on filename of thrift source file and optional suffix"""
result = os.path.join(os.path.split(filename)[0], suffix)
return basename
def toDefinitionHeaderName(filename, genDir=None, debugp=None):
+ """Creates a file name for the public thrift data types based on filename of thrift source file and optional suffix"""
if not genDir:
genDir = toGenDir(filename)
return result
def writeDefinitionHeader(program, filename, genDir=None, debugp=None):
+ """Writes public thrift data types defined in program into a public data types header file. Uses the name of the original
+thrift source, filename, and the optional generated C++ code directory, genDir, to determine the name and location of header file"""
definitionHeader = toDefinitionHeaderName(filename, genDir)
cfile.close()
def toServicesHeaderName(filename, genDir=None, debugp=None):
+ """Creates a file name for the public thrift services based on filename of thrift source file and optional suffix"""
if not genDir:
genDir = toGenDir(filename)
return result
-
def writeServicesHeader(program, filename, genDir=None, debugp=None):
+ """Writes public thrift service abstract base class, client class, and server class for all services defined in program into a public services header file. Uses the name of the original thrift source, filename, and the optional generated C++ code directory, genDir, to determine the name and location of header file"""
servicesHeader = toServicesHeaderName(filename, genDir)
"u16": "U16",
"u32": "U32",
"u64": "U64",
- "float": "Double"
+ "float": "Float",
+ "double": "Double"
}
CPP_COLLECTION_TYPE_IO_METHOD_SUFFIX_MAP = {
}
def typeToIOMethodSuffix(ttype):
+ """Converts type to a name suitable as a suffix with TProtocol primitive read and write methods or with a generated read or write
+method for a complex type"""
if isinstance(ttype, PrimitiveType):
return CPP_PRIMITIVE_TYPE_IO_METHOD_SUFFIX_MAP[ttype.name]
raise Exception, "Unknown type "+str(ttype)
def toReaderCall(value, ttype, reader="iprot", transport="itrans"):
+ """Converts type to a name suitable as a suffix with TProtocol primitive read methods or with a generated read
+method for a complex type"""
suffix = typeToIOMethodSuffix(ttype)
raise Exception, "Unknown type "+str(ttype)
def toWriterCall(value, ttype, writer="oprot", transport="otrans"):
+ """Converts type to a name suitable as a suffix with TProtocol primitive write methods or with a generated write
+method for a complex type"""
suffix = typeToIOMethodSuffix(ttype)
}
""")
-def toCollectionReaderDefinition(ttype):
+def toCollectionReaderDefinition(collection):
+ """Converts collection type to reader function definition"""
- suffix = typeToIOMethodSuffix(ttype)
+ suffix = typeToIOMethodSuffix(collection)
- if isinstance(ttype, MapType):
- keyReaderCall = toReaderCall("key", ttype.keyType)
+ if isinstance(collection, MapType):
+ keyReaderCall = toReaderCall("key", collection.keyType)
- valueReaderCall= toReaderCall("elem", ttype.valueType)
+ valueReaderCall= toReaderCall("elem", collection.valueType)
- if isinstance(ttype, MapType):
- return CPP_READ_MAP_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(ttype),
- keyType=typeToCTypeDeclaration(ttype.keyType),
+ if isinstance(collection, MapType):
+ return CPP_READ_MAP_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(collection),
+ keyType=typeToCTypeDeclaration(collection.keyType),
keyReaderCall=keyReaderCall,
- valueType=typeToCTypeDeclaration(ttype.valueType),
+ valueType=typeToCTypeDeclaration(collection.valueType),
valueReaderCall=valueReaderCall)
else:
- if isinstance(ttype, ListType):
+ if isinstance(collection, ListType):
insert="push_back"
else:
insert="insert"
- return CPP_READ_LIST_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(ttype),
+ return CPP_READ_LIST_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(collection),
valueReaderCall=valueReaderCall,
- valueType=typeToCTypeDeclaration(ttype.valueType),
+ valueType=typeToCTypeDeclaration(collection.valueType),
insert=insert)
-def toCollectionWriterDefinition(ttype):
+def toCollectionWriterDefinition(collection):
+ """Converts collection type to writer function definition"""
- suffix = typeToIOMethodSuffix(ttype)
+ suffix = typeToIOMethodSuffix(collection)
- if isinstance(ttype, MapType):
- keyWriterCall = toWriterCall("ix->first", ttype.keyType)
- valueWriterCall = toWriterCall("ix->second", ttype.valueType)
+ if isinstance(collection, MapType):
+ keyWriterCall = toWriterCall("ix->first", collection.keyType)
+ valueWriterCall = toWriterCall("ix->second", collection.valueType)
else:
- valueWriterCall= toWriterCall("*ix", ttype.valueType)
+ valueWriterCall= toWriterCall("*ix", collection.valueType)
- if isinstance(ttype, MapType):
- return CPP_WRITE_MAP_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(ttype),
- keyType=typeToCTypeDeclaration(ttype.keyType),
+ if isinstance(collection, MapType):
+ return CPP_WRITE_MAP_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(collection),
+ keyType=typeToCTypeDeclaration(collection.keyType),
keyWriterCall=keyWriterCall,
- valueType=typeToCTypeDeclaration(ttype.valueType),
+ valueType=typeToCTypeDeclaration(collection.valueType),
valueWriterCall=valueWriterCall)
else:
- return CPP_WRITE_LIST_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(ttype),
+ return CPP_WRITE_LIST_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(collection),
valueWriterCall=valueWriterCall,
- valueType=typeToCTypeDeclaration(ttype.valueType))
+ valueType=typeToCTypeDeclaration(collection.valueType))
CPP_READ_STRUCT_DEFINITION = Template("""
}
""")
-CPP_WRITE_FIELD_DEFINITION = Template("""
- oprot->writeFieldBegin(otrans, \"${name}\", ${type}, ${id});
- ${fieldWriterCall};
- oprot->writeFieldEnd(otrans);
-""")
-
+CPP_WRITE_FIELD_DEFINITION = Template("""oprot->writeFieldBegin(otrans, \"${name}\", ${type}, ${id}); ${fieldWriterCall}; oprot->writeFieldEnd(otrans)""")
+
CPP_WRITE_STRUCT_DEFINITION = Template("""
uint32_t write_${suffix}("""+CPP_PROTOCOLP+""" oprot, """+CPP_TRANSPORTP+""" otrans, const ${declaration}& value) {
}
""")
-def toStructReaderDefinition(ttype):
+def toStructReaderDefinition(struct):
+ """Converts struct type to reader function definition"""
- suffix = typeToIOMethodSuffix(ttype)
+ suffix = typeToIOMethodSuffix(struct)
# Sort field list in order of increasing ids
fieldList = []
- fieldList+= ttype.fieldList
+ fieldList+= struct.fieldList
fieldList.sort(lambda a,b: a.id - b.id)
fieldSwitch+= " case "+str(field.id)+": "
fieldSwitch+= toReaderCall("value."+field.name, field.type)+"; value.__isset."+field.name+" = true; break;\n"
- return CPP_READ_STRUCT_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(ttype), fieldSwitch=fieldSwitch)
+ return CPP_READ_STRUCT_DEFINITION.substitute(suffix=suffix, declaration=typeToCTypeDeclaration(struct), fieldSwitch=fieldSwitch)
-def toStructWriterDefinition(ttype):
- suffix = typeToIOMethodSuffix(ttype)
+def toStructWriterDefinition(struct):
+ """Converts struct type to writer function definition"""
+
+ suffix = typeToIOMethodSuffix(struct)
- writeCalls = ""
+ fieldWriterCalls = []
- for field in ttype.fieldList:
+ fieldWriterCalls = [CPP_WRITE_FIELD_DEFINITION.substitute(name=field.name,
+ type=toWireType(toCanonicalType(field.type)),
+ id=field.id,
+ fieldWriterCall=toWriterCall("value."+field.name, field.type))+";"
+ for field in struct.fieldList]
- writeCalls+= CPP_WRITE_FIELD_DEFINITION.substitute(name=field.name, type=toWireType(field.type), id=field.id,
- fieldWriterCall=toWriterCall("value."+field.name, field.type))
-
- return CPP_WRITE_STRUCT_DEFINITION.substitute(name=ttype.name, suffix=suffix, declaration=typeToCTypeDeclaration(ttype), fieldWriterCalls=writeCalls)
+ fieldWriterCalls = " "+string.join(fieldWriterCalls, "\n ")
+
+ return CPP_WRITE_STRUCT_DEFINITION.substitute(name=struct.name, suffix=suffix, declaration=typeToCTypeDeclaration(struct), fieldWriterCalls=fieldWriterCalls)
+
+CPP_WRITE_RESULT_STRUCT_DEFINITION = Template("""
+uint32_t write_${suffix}("""+CPP_PROTOCOLP+""" oprot, """+CPP_TRANSPORTP+""" otrans, const ${declaration}& value) {
+
+ uint32_t xfer = 0;
+
+ xfer+= oprot->writeStructBegin(otrans, \"${name}\");
+ if(${value}.__isset.x)
+${fieldWriterCalls}
+ xfer+= oprot->writeFieldStop(otrans);
+ xfer += oprot->writeStructEnd(otrans);
+ return xfer;
+}
+""")
+def toResultStructReaderDefinition(struct):
+ """Converts internal results struct to a reader function definition"""
+ return toStructReaderDefinition(struct)
+
+def toResultStructWriterDefinition(struct):
+ """Converts internal results struct to a reader function definition. The difference between this function and toStructWriterDefinition is that this only sends one field, either success or an exception field, depending on which field is set"""
+
+ suffix = typeToIOMethodSuffix(struct)
+
+ fieldWriterCalls = ["if(value.__isset."+field.name+") { "+toWriterCall("value."+field.name, field.type)+";}" for field in struct.fieldList]
+
+ fieldWriterCalls = " "+string.join(fieldWriterCalls, "\n else ")
+
+ return CPP_WRITE_STRUCT_DEFINITION.substitute(name=struct.name, suffix=suffix, declaration=typeToCTypeDeclaration(struct), fieldWriterCalls=fieldWriterCalls)
+
def toReaderDefinition(ttype):
+ """Converts thrift type to a reader function definition"""
+
if isinstance(ttype, CollectionType):
return toCollectionReaderDefinition(ttype)
raise Exception, "Unsupported type: "+str(ttype)
def toWriterDefinition(ttype):
+ """Converts thrift type to a writer function definition"""
+
if isinstance(ttype, CollectionType):
return toCollectionWriterDefinition(ttype)
raise Exception, "Unsupported type: "+str(ttype)
def toOrderedIOList(ttype, result=None):
+ """Builds a list of types ordered by doing a depth first traverse of all thrift type definitions. This gives us a list from which we can
+generate read/write methods without making forward references."""
+
if not result:
result = []
return result
def toIOMethodImplementations(program):
+ """Generates read and write methods for all non-primitive types in a thrift program as well as for the internal argStruct and resultStruct types for
+all service functions"""
# get ordered list of all types that need marshallers:
result+= toReaderDefinition(function.argsStruct)
result+= toWriterDefinition(function.argsStruct)
result+= toStructDefinition(function.resultStruct)
- result+= toReaderDefinition(function.resultStruct)
- result+= toWriterDefinition(function.resultStruct)
+ result+= toResultStructReaderDefinition(function.resultStruct)
+ result+= toResultStructWriterDefinition(function.resultStruct)
return result;
def toImplementationSourceName(filename, genDir=None, debugp=None):
+ """Creates a file name for the implementation of client stubs, server skeletons, and non-primitive read/write methods."""
if not genDir:
genDir = toGenDir(filename)
return result
def writeImplementationSource(program, filename, genDir=None, debugp=None):
+ """Writes client stub, server skeleton, and non-primitive type I/O functions for all servciesf defined in program into a C/C++ source file. Uses the name of the original
+thrift source, filename, and the optional generated C++ code directory, genDir, to determine the name and location of header file"""
implementationSource = toImplementationSourceName(filename, genDir)
U32_TYPE = PrimitiveType("u32")
U64_TYPE = PrimitiveType("u64")
FLOAT_TYPE = PrimitiveType("float")
+DOUBLE_TYPE = PrimitiveType("double")
PRIMITIVE_MAP = {
"stop" : STOP_TYPE,
"u16": U16_TYPE,
"u32": U32_TYPE,
"u64": U64_TYPE,
- "float": FLOAT_TYPE
+ "float": FLOAT_TYPE,
+ "double": DOUBLE_TYPE
}
""" Collection Types """
def __str__(self):
return self.name+"<"+string.join(map(lambda a: str(a), self.fieldList), ", ")+">"
+class ExceptionType(StructType):
+
+ def __init__(self, symbols, name, fieldList):
+ StructType.__init__(self, symbols, name, fieldList)
+
class Function(Definition):
def __init__(self, symbols, name, resultStruct, argsStruct, ):
def validate(self):
validateFieldList(self.argsStruct.fieldList)
+ validateFieldList(self.resultStruct.fieldList)
def args(self):
return self.argsStruct.fieldList
def returnType(self):
return self.resultStruct.fieldList[0].type
+
+ def exceptions(self):
+ return self.resultStruct.fieldList[1:]
def __str__(self):
- return self.name+"("+string.join(map(lambda a: str(a), self.argsStruct), ", ")+") => "+str(self.resultStruct)
+ return self.name+"("+str(self.argsStruct)+") => "+str(self.resultStruct)
class Service(Definition):
# "CONST",
"DOUBLE",
"ENUM",
- # "EXCEPTION",
+ "EXCEPTION",
# "EXTENDS",
"I08",
"I16",
"STRING",
"STRUCT",
# "SYNCHRONIZED",
+ "THROWS",
"TYPEDEF",
"U08",
"U16",
except ErrorException, e:
self.errors+= e.errors
+ def p_definition_5(self, p):
+ 'definition : exception'
+ self.pdebug("p_definition_5", p)
+ p[0] = p[1]
+ try:
+ self.program.addStruct(p[0])
+ except ErrorException, e:
+ self.errors+= e.errors
+
def p_typedef(self, p):
'typedef : TYPEDEF definitiontype ID'
self.pdebug("p_typedef", p)
except ErrorException, e:
self.errors+= e.errors
+ def p_exception(self, p):
+ 'exception : EXCEPTION ID LBRACE fieldlist RBRACE'
+ self.pdebug("p_struct", p)
+ p[0] = ExceptionType(p, p[2], p[4])
+
+ try:
+ p[0].validate()
+ except ErrorException, e:
+ self.errors+= e.errors
+
def p_service(self, p):
'service : SERVICE ID LBRACE functionlist RBRACE'
self.pdebug("p_service", p)
self.errors+= e.errors
def p_functionlist_1(self, p):
- 'functionlist : functionlist function'
+ 'functionlist : function COMMA functionlist'
self.pdebug("p_functionlist_1", p)
- p[0] = p[1] + (p[2],)
+ p[0] = (p[1],) + p[3]
def p_functionlist_2(self, p):
- 'functionlist :'
+ 'functionlist : function'
self.pdebug("p_functionlist_2", p)
+ p[0] = (p[1],)
+
+ def p_functionlist_3(self, p):
+ 'functionlist : '
+ self.pdebug("p_functionlist_3", p)
p[0] = ()
def p_function(self, p):
- 'function : functiontype functionmodifiers ID LPAREN fieldlist RPAREN'
+ 'function : functiontype functionmodifiers ID LPAREN fieldlist RPAREN exceptionspecifier'
self.pdebug("p_function", p)
- resultStruct = StructType(p, p[3]+"_result", (Field(p, p[1], Identifier(None, "success", 1)),))
+ resultStruct = StructType(p, p[3]+"_result", (Field(p, p[1], Identifier(None, "success", 0)),)+p[7])
p[0] = Function(p, p[3], resultStruct, StructType(p, p[3]+"_args", p[5]))
try:
p[0] = ()
def p_fieldlist_1(self, p):
- 'fieldlist : fieldlist COMMA field'
+ 'fieldlist : field COMMA fieldlist'
self.pdebug("p_fieldlist_1", p)
- p[0] = p[1] + (p[3],)
+ p[0] = (p[1],) + p[3]
def p_fieldlist_2(self, p):
'fieldlist : field'
self.pdebug("p_field_2", p)
p[0] = Field(p, p[1], Identifier(None, p[2]))
+ def p_exceptionSpecifier_1(self, p):
+ 'exceptionspecifier : THROWS LPAREN fieldlist RPAREN'
+ self.pdebug("p_exceptionspecifier", p)
+ p[0] = p[3]
+
+ def p_exceptionSpecifier_2(self, p):
+ 'exceptionspecifier : empty'
+ self.pdebug("p_exceptionspecifier", p)
+ p[0] = ()
+
def p_definitiontype_1(self, p):
'definitiontype : basetype'
self.pdebug("p_definitiontype_1", p)
self.pdebug("p_listtype", p)
p[0] = ListType(p, p[3])
+ def p_empty(self, p):
+ "empty : "
+ pass
+
def p_error(self, p):
# p_error is called with an empty token if eof was encountered unexpectedly.
if not p:
def pdebug(self, name, p):
if self.debug:
- print(name+"("+string.join(map(lambda t: "<<"+str(t)+">>", p), ", ")+")")
+ print(name+"("+string.join(["P["+str(ix)+"]<<"+str(p[ix])+">>" for ix in range(len(p))], ", ")+")")
def __init__(self, **kw):
self.debug = kw.get('debug', 0)