BlockIt
|
00001 #................................................................................ 00002 # The MIT License 00003 00004 # Copyright (c) 2009-2010 David Car, david.car7@gmail.com 00005 # Copyright (c) 2009-2010 Michael List, michael.list@gmail.com 00006 00007 # Permission is hereby granted, free of charge, to any person obtaining a copy 00008 # of this software and associated documentation files (the "Software"), to deal 00009 # in the Software without restriction, including without limitation the rights 00010 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00011 # copies of the Software, and to permit persons to whom the Software is 00012 # furnished to do so, subject to the following conditions: 00013 00014 # The above copyright notice and this permission notice shall be included in all 00015 # copies or substantial portions of the Software. 00016 00017 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00020 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00021 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00022 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00023 # SOFTWARE. 00024 #................................................................................ 00025 from blockit.parsers import pyp as pp 00026 import blockit.basegrammar as gram 00027 import blockit.m4.grammars as m4gram 00028 00029 __doc__ = """ 00030 (C) 2010 Michael List, michael.list@gmail.com 00031 (C) 2010 David Car, david.car7@gmail.com 00032 00033 Some of these grammars were hacked from the PyParsing UnderDevelopment site and 00034 likely then follow the same license as pyparsing itself. 00035 00036 """ 00037 00038 # Create forward declarations for possible recursive types 00039 STRUCTDECL = pp.Forward() 00040 ENUMDECL = pp.Forward() 00041 00042 # Basic identifiers and punctuation 00043 CPLUSPLUSLINECOMMENT = pp.Literal("//") + pp.restOfLine 00044 IDENT = pp.Word( pp.alphas+"_", pp.alphanums+"_$" ) 00045 INTEGER = pp.Word( pp.nums ) 00046 SEMI = pp.Literal(";").suppress() 00047 COMMA = pp.Literal(",").suppress() 00048 LBRACE = pp.Literal("{").suppress() 00049 RBRACE = pp.Literal("}").suppress() 00050 LBRACK = pp.Literal("[").suppress() 00051 RBRACK = pp.Literal("]").suppress() 00052 EQUALS = pp.Literal("=").suppress() 00053 LPAREN = pp.Literal("(").suppress() 00054 RPAREN = pp.Literal(")").suppress() 00055 CONST = pp.Keyword("const") 00056 ELLIPSIS = pp.Literal("...") 00057 ENUM = pp.Keyword("enum") 00058 EXTERN = pp.Keyword("extern").suppress() 00059 LONG = pp.Keyword("long") 00060 SHORT = pp.Keyword("short") 00061 STATIC = pp.Keyword("static").suppress() 00062 STRUCT = pp.Keyword("struct") 00063 VOID = pp.Keyword("void") 00064 ATTRIBUTE = pp.Keyword("__attribute__") 00065 PARENEDVALUE = LPAREN + pp.Word(pp.alphanums) + RPAREN 00066 ATTRIBUTES = pp.Group(ATTRIBUTE + pp.Literal("((") + pp.OneOrMore((pp.Word(pp.alphanums)|PARENEDVALUE)) + pp.Literal("))")).suppress() 00067 INLINE = pp.Keyword("__inline__").suppress() 00068 UNSIGNED = pp.Keyword("unsigned") 00069 POINTERNOTATION = pp.Optional(pp.Word("*"), default=None) 00070 TYPEDEF = pp.Keyword("typedef").suppress() 00071 00072 TYPENAME = IDENT 00073 VARNAME = IDENT 00074 00075 ARRAYSIZESPECIFIER = INTEGER | IDENT 00076 INTRINSICSPEC = pp.Optional(UNSIGNED|CONST) + pp.Optional(pp.OneOrMore(LONG|SHORT|UNSIGNED|CONST)) + \ 00077 pp.oneOf("int long short double char void size_t") + pp.Optional(CONST) 00078 LONGLONGSPEC = pp.Optional(UNSIGNED|CONST) + LONG + LONG # Necessary... 00079 STRUCTTYPESPEC = pp.Optional(CONST) + STRUCT + VARNAME 00080 STRUCTPROTOTYPE = pp.lineStart + STRUCTTYPESPEC + SEMI 00081 ENUMTYPESPEC = pp.Optional(CONST) + ENUM + VARNAME 00082 TYPESPEC = (INTRINSICSPEC|LONGLONGSPEC|STRUCTTYPESPEC|ENUMTYPESPEC|IDENT) 00083 00084 BITFIELDSPEC = ":" + ARRAYSIZESPECIFIER 00085 VARNAMESPEC = ( VARNAME + pp.Optional( BITFIELDSPEC | ( LBRACK + ARRAYSIZESPECIFIER + RBRACK ))) 00086 ASSIGNMENTFIELD = pp.Group( VARNAMESPEC + EQUALS + \ 00087 ( gram.HEX_NUM | gram.ENGINEERING_NUM | gram.DECIMAL_NUM | gram.INTEGER | gram.NUM ) ) 00088 # For variables with array indices we must have default=None to make sure we put the integers in the right 00089 # spots. int d=1; int d[1]; both parse to ['d','1'] if you don't. Want int d=1 --> ['d', None, '1'] 00090 VARNAMESPECARR = ( VARNAME + pp.Optional( BITFIELDSPEC | ( LBRACK + ARRAYSIZESPECIFIER + RBRACK ), default=None)) 00091 ASSIGNMENTFIELDARR = pp.Group( VARNAMESPECARR + EQUALS + \ 00092 ( gram.HEX_NUM | gram.ENGINEERING_NUM | gram.DECIMAL_NUM | gram.INTEGER | gram.NUM ) ) 00093 00094 00095 # Specification, i.e. enum cudaSuccess, struct dim3, etc. 00096 ENUMSPEC = ENUM + VARNAMESPEC 00097 STRUCTSPEC = STRUCT + VARNAMESPEC 00098 00099 00100 #....................................................................... 00101 # Structure definitions 00102 #....................................................................... 00103 MEMBERDECL = pp.Group( ( TYPESPEC | TYPENAME | ENUMSPEC ) + POINTERNOTATION + \ 00104 pp.Group( pp.delimitedList( pp.Group(ASSIGNMENTFIELDARR | VARNAMESPECARR) ) ) + SEMI ) | STRUCTDECL 00105 MEMBERENUMDECL = pp.Group( ENUMSPEC + POINTERNOTATION + \ 00106 pp.Group( pp.delimitedList( pp.Group(ASSIGNMENTFIELDARR | VARNAMESPECARR) ) ) + SEMI ) | STRUCTDECL 00107 MEMBERSTRUCTDECL = pp.Group( STRUCTSPEC + POINTERNOTATION + \ 00108 pp.Group( pp.delimitedList( pp.Group(ASSIGNMENTFIELDARR | VARNAMESPECARR) ) ) + SEMI ) | STRUCTDECL 00109 00110 # Structs 00111 STRUCTDECL << pp.Group( pp.Optional(TYPEDEF) + STRUCT + pp.Optional(ATTRIBUTES) + pp.Optional(IDENT, default=None) + \ 00112 pp.Group( LBRACE + pp.ZeroOrMore( MEMBERDECL | MEMBERENUMDECL | MEMBERSTRUCTDECL ) + RBRACE) + \ 00113 POINTERNOTATION + pp.Optional(VARNAMESPEC, default=None) + SEMI ) 00114 CSTRUCTBNF = STRUCTDECL 00115 CSTRUCTBNF.ignore( pp.cStyleComment ) # never know where these will crop up! 00116 CSTRUCTBNF.ignore( CPLUSPLUSLINECOMMENT ) # or these either 00117 00118 #....................................................................... 00119 # Enumerator definitions 00120 #....................................................................... 00121 ENUMDECL << pp.Group( pp.Optional(TYPEDEF) + ENUM + pp.Optional(IDENT, default=None) + \ 00122 pp.Group( LBRACE + pp.ZeroOrMore( (ASSIGNMENTFIELD|VARNAMESPEC) + COMMA ) + pp.ZeroOrMore( (ASSIGNMENTFIELD|VARNAMESPEC) ) \ 00123 + RBRACE ) + POINTERNOTATION + pp.Optional(VARNAMESPEC, default=None) + SEMI ) 00124 CENUMBNF = ENUMDECL 00125 CENUMBNF.ignore( pp.cStyleComment ) 00126 CENUMBNF.ignore( CPLUSPLUSLINECOMMENT ) 00127 00128 #....................................................................... 00129 # Typedef definitions 00130 #....................................................................... 00131 TYPEDEFSPEC = pp.Keyword("typedef") + \ 00132 pp.Group((TYPESPEC ^ STRUCTSPEC ^ ENUMSPEC ^ IDENT) + POINTERNOTATION) + \ 00133 VARNAMESPEC 00134 TYPEDEFDECL = pp.Group( TYPEDEFSPEC + SEMI ) 00135 TYPEDEFBNF = TYPEDEFDECL 00136 TYPEDEFBNF.ignore( pp.cStyleComment ) 00137 TYPEDEFBNF.ignore( CPLUSPLUSLINECOMMENT ) 00138 00139 #....................................................................... 00140 # Function prototypes 00141 #....................................................................... 00142 # The basic prototype is for preprocessed source 00143 PROTOSPEC = pp.Group(pp.Optional(EXTERN|STATIC) + TYPESPEC + POINTERNOTATION ) + \ 00144 VARNAME + pp.Group( LPAREN + \ 00145 (pp.delimitedList(pp.Group(TYPESPEC + POINTERNOTATION + VARNAMESPEC)|ELLIPSIS, delim=',')|VOID) + \ 00146 RPAREN ) 00147 # The generic prototype is for unprocessed source 00148 GENERICPROTOSPEC = pp.OneOrMore((EXTERN | TYPESPEC | VARNAME) + POINTERNOTATION) + pp.Group( LPAREN + \ 00149 (pp.delimitedList(pp.Group(TYPESPEC + POINTERNOTATION + VARNAMESPEC)|ELLIPSIS, delim=',')|VOID) + \ 00150 RPAREN ) 00151 00152 #PROTODECL = pp.LineStart() + pp.Group( PROTOSPEC + SEMI ) 00153 PROTODECL = pp.Group( PROTOSPEC + SEMI ) 00154 PROTOBNF = PROTODECL 00155 PROTOBNF.ignore( pp.cStyleComment ) 00156 PROTOBNF.ignore( CPLUSPLUSLINECOMMENT ) 00157 #GPROTODECL = pp.LineStart() + pp.Group( GENERICPROTOSPEC + SEMI ) 00158 GPROTODECL = pp.Group( GENERICPROTOSPEC + SEMI ) 00159 GPROTOBNF = GPROTODECL 00160 GPROTOBNF.ignore( pp.cStyleComment ) 00161 GPROTOBNF.ignore( CPLUSPLUSLINECOMMENT ) 00162 00163 if __name__ == "__main__": 00164 00165 import unittest 00166 00167 #======================================================================= 00168 class TestCGrammar(unittest.TestCase): 00169 #======================================================================= 00170 testData1 = """ 00171 struct { 00172 long a; 00173 short b; 00174 char c[32]; /* comment */ 00175 } a; 00176 00177 struct { 00178 int i; 00179 } dimple; 00180 """ 00181 00182 testData2 = """ 00183 union { 00184 long a; 00185 long* a; 00186 long** a; 00187 long*** a; 00188 long**** a; 00189 long *a; 00190 long **a; 00191 struct { 00192 int x; 00193 int y; 00194 } pt; // this is an embedded struct 00195 struct { 00196 int x,y; 00197 struct { 00198 char* a; 00199 char* b; 00200 } inner; 00201 } pt2; 00202 struct { 00203 int x; 00204 int y; 00205 }* coordPtr; /* this is just a pointer to a struct */ 00206 short b; 00207 char c[32]; 00208 char d[MAX_LENGTH /* + 1 to make room for terminating null */ ]; 00209 char* name; 00210 char *name2; /* no one can agree where the '*' should go */ 00211 int bitfield:5; /* this is rare, but not hard to add to parse grammar */ 00212 int bitfield2:BIT2LEN; 00213 void* otherData; 00214 } a; 00215 """ 00216 00217 testData3 = """ 00218 struct cudaChannelFormatDesc 00219 { 00220 int x; /**< x */ 00221 int y; /**< y */ 00222 int z; /**< z */ 00223 int w; /**< w */ 00224 enum cudaChannelFormatKind f; /**< Channel format kind */ 00225 }; 00226 00227 struct cudaArray; 00228 00229 struct cudaPitchedPtr 00230 { 00231 void *ptr; /**< Pointer to allocated memory */ 00232 size_t pitch; /**< Pitch of allocated memory in bytes */ 00233 size_t xsize; /**< Logical width of allocation in elements */ 00234 size_t ysize; /**< Logical height of allocation in elements */ 00235 }; 00236 00237 struct cudaExtent 00238 { 00239 size_t width; /**< Width in elements when referring to array memory, in bytes when referring to linear memory */ 00240 size_t height; /**< Height in elements */ 00241 size_t depth; /**< Depth in elements */ 00242 }; 00243 00244 struct cudaPos 00245 { 00246 size_t x; /**< x */ 00247 size_t y; /**< y */ 00248 size_t z; /**< z */ 00249 }; 00250 00251 struct cudaMemcpy3DParms 00252 { 00253 struct cudaArray *srcArray; /**< Source memory address */ 00254 struct cudaPos srcPos; /**< Source position offset */ 00255 struct cudaPitchedPtr srcPtr; /**< Pitched source memory address */ 00256 00257 struct cudaArray *dstArray; /**< Destination memory address */ 00258 struct cudaPos dstPos; /**< Destination position offset */ 00259 struct cudaPitchedPtr dstPtr; /**< Pitched destination memory address */ 00260 00261 struct cudaExtent extent; /**< Requested memory copy size */ 00262 enum cudaMemcpyKind kind; /**< Type of transfer */ 00263 }; 00264 struct cudaFuncAttributes 00265 { 00266 size_t sharedSizeBytes; 00267 size_t constSizeBytes; 00268 size_t localSizeBytes; 00269 int maxThreadsPerBlock; 00270 int numRegs; 00271 int ptxVersion; 00272 int binaryVersion; 00273 int __cudaReserved[6]; 00274 }; 00275 00276 struct cudaDeviceProp 00277 { 00278 char name[256]; /**< ASCII string identifying device */ 00279 size_t totalGlobalMem; /**< Global memory available on device in bytes */ 00280 size_t sharedMemPerBlock; /**< Shared memory available per block in bytes */ 00281 int regsPerBlock; /**< 32-bit registers available per block */ 00282 int warpSize; /**< Warp size in threads */ 00283 size_t memPitch; /**< Maximum pitch in bytes allowed by memory copies */ 00284 int maxThreadsPerBlock; /**< Maximum number of threads per block */ 00285 int maxThreadsDim[3]; /**< Maximum size of each dimension of a block */ 00286 int maxGridSize[3]; /**< Maximum size of each dimension of a grid */ 00287 int clockRate; /**< Clock frequency in kilohertz */ 00288 size_t totalConstMem; /**< Constant memory available on device in bytes */ 00289 int major; /**< Major compute capability */ 00290 int minor; /**< Minor compute capability */ 00291 size_t textureAlignment; /**< Alignment requirement for textures */ 00292 int deviceOverlap; /**< Device can concurrently copy memory and execute a kernel */ 00293 int multiProcessorCount; /**< Number of multiprocessors on device */ 00294 int kernelExecTimeoutEnabled; /**< Specified whether there is a run time limit on kernels */ 00295 int integrated; /**< Device is integrated as opposed to discrete */ 00296 int canMapHostMemory; /**< Device can map host memory with cudaHostAlloc/cudaHostGetDevicePointer */ 00297 int computeMode; /**< Compute mode (See ::cudaComputeMode) */ 00298 int maxTexture1D; /**< Maximum 1D texture size */ 00299 int maxTexture2D[2]; /**< Maximum 2D texture dimensions */ 00300 int maxTexture3D[3]; /**< Maximum 3D texture dimensions */ 00301 int maxTexture2DArray[3]; /**< Maximum 2D texture array dimensions */ 00302 size_t surfaceAlignment; /**< Alignment requirements for surfaces */ 00303 int concurrentKernels; /**< Device can possibly execute multiple kernels concurrently */ 00304 int ECCEnabled; /**< Device has ECC support enabled */ 00305 int pciBusID; /**< PCI bus ID of the device */ 00306 int pciDeviceID; /**< PCI device ID of the device */ 00307 int tccDriver; /**< 1 if device is a Tesla device using TCC driver, 0 otherwise */ 00308 int __cudaReserved[21]; 00309 }; 00310 00311 struct; 00312 00313 typedef struct aTypeDef ThisIsWRONG; 00314 """ 00315 00316 def setUp(self): pass 00317 00318 def tearDown(self): pass 00319 00320 #------------------------------------------------------------------- 00321 def testScanMultiplePrototype(self): 00322 #------------------------------------------------------------------- 00323 """Checks scanning of multiple preprocessed prototypes""" 00324 00325 bnf = PROTOBNF 00326 ctr = 0 00327 for m,s,e in bnf.scanString(""" 00328 int cg_state_read(char **StateDescription); 00329 int cg_state_write(char const * StateDescription); 00330 """): 00331 ctr += 1 00332 self.failUnlessEqual(ctr, 2, "Failed to find correct number of matches") 00333 00334 00335 #------------------------------------------------------------------- 00336 def testParsePrototype(self): 00337 #------------------------------------------------------------------- 00338 """Checks parsing of preprocessed prototypes""" 00339 00340 bnf = PROTOBNF 00341 try: 00342 output = bnf.parseString("extern cudaError_t cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device);") 00343 except: 00344 self.fail("Failed to parse string") 00345 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00346 00347 try: 00348 output = bnf.parseString("CUresult cuGraphicsMapResources(unsigned int count, CUgraphicsResource *resources, CUstream hStream);") 00349 except: 00350 self.fail("Failed to parse string") 00351 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00352 00353 try: 00354 output = bnf.parseString("int myfunc(struct jdog *damoney, ...);") 00355 except: 00356 self.fail("Failed to parse string") 00357 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00358 00359 try: 00360 output = bnf.parseString("extern cudaError_t \ 00361 cudaGraphicsSubResourceGetMappedArray(struct cudaArray **array, \ 00362 cudaGraphicsResource_t resource, unsigned int arrayIndex, unsigned int mipLevel);") 00363 except: 00364 self.fail("Failed to parse string") 00365 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00366 00367 try: 00368 output = bnf.parseString("int cg_state_read(char **StateDescription);") 00369 except: 00370 self.fail("Failed to parse string") 00371 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00372 00373 try: 00374 output = bnf.parseString("int cg_state_write(char const * StateDescription);") 00375 except: 00376 self.fail("Failed to parse string") 00377 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00378 self.failUnlessEqual(len(output[0]),3,"Output dimensions incorrect") 00379 self.failUnlessEqual(len(output[0][0]),2,"Output dimensions incorrect") 00380 self.failUnlessEqual(output[0][1],"cg_state_write","Incorrect prototype name found!") 00381 00382 00383 #------------------------------------------------------------------- 00384 def testParseGenericPrototype(self): 00385 #------------------------------------------------------------------- 00386 """Checks parsing of non-preprocessed prototypes""" 00387 00388 bnf = GPROTOBNF 00389 try: 00390 output = bnf.parseString("extern __host__ cudaError_t CUDARTAPI cudaGetDevice(void *devPtr);") 00391 except: 00392 self.fail("Failed to parse string") 00393 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00394 00395 try: 00396 output = bnf.parseString("extern __host__ cudaError_t CUDARTAPI cudaSetDevice(int *device);") 00397 except: 00398 self.fail("Failed to parse string") 00399 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00400 00401 try: 00402 output = bnf.parseString("extern __host__ cudaError_t __stdcall \ 00403 cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags);") 00404 except: 00405 self.fail("Failed to parse string") 00406 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00407 00408 try: 00409 output = bnf.parseString("extern cudaError_t cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device);") 00410 except: 00411 self.fail("Failed to parse string") 00412 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00413 00414 try: 00415 output = bnf.parseString("CUresult cuGraphicsMapResources(unsigned int count, CUgraphicsResource *resources, CUstream hStream);") 00416 except: 00417 self.fail("Failed to parse string") 00418 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00419 00420 try: 00421 output = bnf.parseString("extern cudaError_t \ 00422 cudaGraphicsSubResourceGetMappedArray(struct cudaArray **array, \ 00423 cudaGraphicsResource_t resource, unsigned int arrayIndex, unsigned int mipLevel);") 00424 except: 00425 self.fail("Failed to parse string") 00426 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00427 00428 try: 00429 output = bnf.parseString("int cg_state_read(char **StateDescription);") 00430 except: 00431 self.fail("Failed to parse string") 00432 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00433 00434 try: 00435 output = bnf.parseString("int cg_state_write(char const * StateDescription);") 00436 except: 00437 self.fail("Failed to parse string") 00438 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00439 00440 00441 #------------------------------------------------------------------- 00442 def testParseStructTypedef(self): 00443 #------------------------------------------------------------------- 00444 """Checks parsing of struct defined in typedef""" 00445 00446 bnf = CSTRUCTBNF 00447 try: 00448 output = bnf.parseString(""" 00449 typedef struct cuda_error { 00450 int success; /** something */ 00451 long failure; /** something */ 00452 unsigned short int badness; /** something */ 00453 } CUresult; 00454 """) 00455 except: 00456 self.fail("Failed to parse string") 00457 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00458 00459 00460 #------------------------------------------------------------------- 00461 def testParseEnumTypedef(self): 00462 #------------------------------------------------------------------- 00463 """Checks parsing of enum defined in typedef""" 00464 00465 bnf = CENUMBNF 00466 00467 try: 00468 output = bnf.parseString(""" 00469 typedef enum cuda_error { 00470 success = 1, /** something */ 00471 failure = 2, /** something */ 00472 badness = 3 /** something */ 00473 } CUresult; 00474 """) 00475 except: 00476 self.fail("Failed to parse string") 00477 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00478 00479 try: 00480 output = bnf.parseString(""" 00481 typedef enum { success = 1, failure = 2, badness = 3 } CUresult_t; 00482 """) 00483 except: 00484 self.fail("Failed to parse string") 00485 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00486 00487 00488 #------------------------------------------------------------------- 00489 def testParseBasicTypedef(self): 00490 #------------------------------------------------------------------- 00491 """Checks to ensure proper parsing of simple typedefs""" 00492 00493 bnf = TYPEDEFBNF 00494 00495 try: 00496 output = bnf.parseString("typedef int int_t;") 00497 except: 00498 self.fail("Failed to parse string") 00499 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00500 self.failUnlessEqual(len(output[0]),3,"Length of result inappropriate") 00501 00502 try: 00503 output = bnf.parseString("typedef void* GLPtr;") 00504 except: 00505 self.fail("Failed to parse string") 00506 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00507 self.failUnlessEqual(len(output[0]),3,"Length of result inappropriate") 00508 00509 try: 00510 output = bnf.parseString("typedef struct cudaError cudaError_t;") 00511 except: 00512 self.fail("Failed to parse string") 00513 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00514 self.failUnlessEqual(len(output[0]),3,"Length of result inappropriate") 00515 00516 try: 00517 output = bnf.parseString("typedef enum myEnum cuda_returns;") 00518 except: 00519 self.fail("Failed to parse string") 00520 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00521 self.failUnlessEqual(len(output[0]),3,"Length of result inappropriate") 00522 00523 try: 00524 output = bnf.parseString("typedef unsigned long long CUdeviceptr;") 00525 except: 00526 self.fail("Failed to parse string") 00527 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00528 self.failUnlessEqual(len(output[0]),3,"Length of result inappropriate") 00529 00530 try: 00531 output = bnf.parseString("typedef double2 cuDoubleComplex;") 00532 except: 00533 self.fail("Failed to parse string") 00534 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00535 self.failUnlessEqual(len(output[0]),3,"Length of result inappropriate") 00536 self.failUnlessEqual(output[0][0], "typedef") 00537 self.failUnlessEqual(len(output[0][1]), 2) 00538 self.failUnlessEqual(output[0][2], "cuDoubleComplex") 00539 00540 00541 #------------------------------------------------------------------- 00542 def testParseBasicEnum(self): 00543 #------------------------------------------------------------------- 00544 """Checks to ensure proper parsing of simple enums""" 00545 00546 bnf = CENUMBNF 00547 00548 try: 00549 output = bnf.parseString("enum { my = 3, yours = 0x01 };") 00550 except: 00551 self.fail("Failed to parse string") 00552 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00553 self.failUnlessEqual(len(output[0]),5,"Length of result inappropriate") 00554 00555 try: 00556 output = bnf.parseString("enum dum { a, b, c, d };") 00557 except: 00558 self.fail("Failed to parse string") 00559 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00560 self.failUnlessEqual(len(output[0]),5,"Length of result inappropriate") 00561 00562 00563 #------------------------------------------------------------------- 00564 def testParseBasicStruct(self): 00565 #------------------------------------------------------------------- 00566 """Checks to ensure proper parsing of simple structs""" 00567 00568 bnf = CSTRUCTBNF 00569 bnf.ignore( m4gram.POUNDLINE ) 00570 try: 00571 output = bnf.parseString("struct {\nunsigned int x, y, z;\n\ 00572 \n __host__ something something;\n __host__ something something;\n };") 00573 self.fail("Parsed invalid string") 00574 except: 00575 pass 00576 00577 try: 00578 output = bnf.parseString("struct my_struct {\nunsigned int x, y, z;\n\ 00579 \n something something;\n something something;\n };") 00580 except: 00581 self.fail("Failed to parse string") 00582 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00583 self.failUnlessEqual(len(output[0]),5,"Length of result inappropriate") 00584 00585 try: 00586 output = bnf.parseString("struct my_struct {\nunsigned int x, y, z;\n\ 00587 \n something something[15];\n something something=4;\n };") 00588 except: 00589 self.fail("Failed to parse string") 00590 self.failUnlessEqual(len(output),1,"Output dimensions incorrect") 00591 self.failUnlessEqual(len(output[0]),5,"Length of result inappropriate") 00592 00593 #------------------------------------------------------------------- 00594 def testParseStruct(self): 00595 #------------------------------------------------------------------- 00596 """Checks parsing of structs""" 00597 00598 bnf = CSTRUCTBNF 00599 00600 ctr = 0 00601 for match,s,e in bnf.scanString( self.testData1 ): 00602 ctr += 1 00603 self.failUnlessEqual(len(match),1,"Match structure is too long") 00604 self.assertTrue(len(match[0]) == 5,"Match result not correct") 00605 self.failUnlessEqual(ctr,2,"Not enough structs parsed") 00606 00607 ctr = 0 00608 for match,s,e in bnf.scanString( self.testData2 ): 00609 ctr += 1 00610 self.failUnlessEqual(len(match),1,"Match structure is too long") 00611 self.assertTrue(len(match[0]) == 5,"Match result not correct") 00612 self.failUnlessEqual(ctr,3,"Wrong number of structs parsed") 00613 00614 ctr = 0 00615 for match,s,e in bnf.scanString( self.testData3 ): 00616 ctr += 1 00617 self.failUnlessEqual(len(match),1,"Match structure is too long") 00618 self.assertTrue(len(match[0]) == 5,"Match result not correct") 00619 self.failUnlessEqual(ctr,7,"Not enough structs parsed") 00620 00621 try: 00622 output = bnf.parseString("struct mystruct {\nchar name[256];\nint i;\ndouble d=4.0, f=3.0;\n};") 00623 except: 00624 self.fail("Failed to parse string") 00625 self.failUnlessEqual(len(output[0]),5,"Match result not correct") 00626 00627 try: 00628 output = bnf.parseString("struct __attribute__((aligned (8))) mystruct {};") 00629 except: 00630 self.fail("Failed to parse string") 00631 self.failUnlessEqual(len(output[0]),5,"Match result not correct") 00632 00633 00634 #------------------------------------------------------------------- 00635 def testParseStructPrototype(self): 00636 #------------------------------------------------------------------- 00637 """Checks parsing of struct prototypes""" 00638 00639 bnf = STRUCTPROTOTYPE 00640 00641 try: 00642 output = bnf.parseString( "struct mystruct;" ) 00643 except: 00644 self.fail("Failed to parse string") 00645 self.failUnlessEqual(len(output),2,"Match structure is too long") 00646 self.failUnlessEqual(output[0],"struct","Failed to parse correctly") 00647 self.failUnlessEqual(output[1],"mystruct","Failed to parse correctly") 00648 00649 00650 #------------------------------------------------------------------- 00651 def testVarNameSpec(self): 00652 #------------------------------------------------------------------- 00653 """Checks parsing of variable names""" 00654 00655 bnf = VARNAMESPEC 00656 00657 try: 00658 output = bnf.parseString("myvar[16]") 00659 except: 00660 self.fail("Failed to parse string") 00661 self.failUnlessEqual(len(output),2,"Did not parse string") 00662 00663 try: 00664 output = bnf.parseString("myvar") 00665 except: 00666 self.fail("Failed to parse string") 00667 self.failUnlessEqual(len(output),1,"Did not parse string properly") 00668 00669 00670 #------------------------------------------------------------------- 00671 def testIntrinsicSpec(self): 00672 #------------------------------------------------------------------- 00673 """Tests capture of intrinsic variable declaration""" 00674 00675 bnf = INTRINSICSPEC 00676 00677 try: 00678 output = bnf.parseString("unsigned long int") 00679 except: 00680 self.fail("Failed to parse string") 00681 self.failUnlessEqual(len(output),3) 00682 self.failUnlessEqual(output[0],"unsigned") 00683 self.failUnlessEqual(output[1],"long") 00684 self.failUnlessEqual(output[2],"int") 00685 00686 try: 00687 output = bnf.parseString("unsigned long long int") 00688 except: 00689 self.fail("Failed to parse string") 00690 self.failUnlessEqual(len(output),4) 00691 self.failUnlessEqual(output[0],"unsigned") 00692 self.failUnlessEqual(output[1],"long") 00693 self.failUnlessEqual(output[2],"long") 00694 self.failUnlessEqual(output[3],"int") 00695 00696 00697 #------------------------------------------------------------------- 00698 def testTypeSpec(self): 00699 #------------------------------------------------------------------- 00700 """Tests type specification capturing""" 00701 00702 bnf = TYPESPEC 00703 00704 try: 00705 output = bnf.parseString("unsigned long long") 00706 except: 00707 self.fail("Failed to parse string") 00708 self.failUnlessEqual(len(output),3) 00709 self.failUnlessEqual(output[0],"unsigned") 00710 self.failUnlessEqual(output[1],"long") 00711 self.failUnlessEqual(output[2],"long") 00712 00713 try: 00714 output = bnf.parseString("char const") 00715 except: 00716 self.fail("Failed to parse string") 00717 self.failUnlessEqual(len(output),2) 00718 self.failUnlessEqual(output[0],"char") 00719 self.failUnlessEqual(output[1],"const") 00720 00721 00722 suite = unittest.TestLoader().loadTestsFromTestCase(TestCGrammar) 00723 unittest.TextTestRunner(verbosity=2).run(suite)