BlockIt
grammars.py
Go to the documentation of this file.
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)
 All Classes Namespaces Files Functions Variables Properties