cmLex.h/c : Added cmLexTokenIsUnsigned() and cmLexTokenIsSignlePrecision().
This commit is contained in:
parent
2e1c77f150
commit
b4d99528f9
173
cmLex.c
173
cmLex.c
@ -7,6 +7,12 @@
|
|||||||
#include "cmMallocDebug.h"
|
#include "cmMallocDebug.h"
|
||||||
#include "cmFile.h"
|
#include "cmFile.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kRealFloatLexFl = 0x01,
|
||||||
|
kIntUnsignedLexFl = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned code;
|
unsigned code;
|
||||||
@ -29,6 +35,7 @@ cmLexErrorRecd cmLexErrorArray[] =
|
|||||||
{ kMemAllocErrLexRC, "An attempted memory allocation failed"},
|
{ kMemAllocErrLexRC, "An attempted memory allocation failed"},
|
||||||
{ kEofRC, "The end of the input text was encountered (this is a normal condition not an error)"},
|
{ kEofRC, "The end of the input text was encountered (this is a normal condition not an error)"},
|
||||||
{ kInvalidLexTIdLexRC, "An invalid token id was encountered."},
|
{ kInvalidLexTIdLexRC, "An invalid token id was encountered."},
|
||||||
|
{ kSignErrorLexRC, "A signed integer has a 'u' or 'U' suffix."},
|
||||||
{ kInvalidLexRC, "Unknown lexer error code." }
|
{ kInvalidLexRC, "Unknown lexer error code." }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,6 +82,7 @@ typedef struct cmLex_str
|
|||||||
|
|
||||||
cmChar_t* textBuf; // text buf used by cmLexSetFile()
|
cmChar_t* textBuf; // text buf used by cmLexSetFile()
|
||||||
|
|
||||||
|
unsigned attrFlags; // used to store the int and real suffix type flags
|
||||||
} cmLex;
|
} cmLex;
|
||||||
|
|
||||||
|
|
||||||
@ -148,7 +156,7 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
unsigned n = 0; // decimal point counter
|
unsigned n = 0; // decimal point counter
|
||||||
unsigned d = 0; // digit counter
|
unsigned d = 0; // digit counter
|
||||||
bool fl = false; // true if this real includes an exponent
|
bool fl = false; // expo flag
|
||||||
|
|
||||||
for(; i<cn && n<=1; ++i)
|
for(; i<cn && n<=1; ++i)
|
||||||
{
|
{
|
||||||
@ -170,10 +178,12 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
// if there was at least one digit and the next char is an 'e'
|
// if there was at least one digit and the next char is an 'e'
|
||||||
if( d>0 && i<cn && (cp[i] == 'e' || cp[i] == 'E') )
|
if( d>0 && i<cn && (cp[i] == 'e' || cp[i] == 'E') )
|
||||||
{
|
{
|
||||||
d=0;
|
unsigned e=0;
|
||||||
++i;
|
++i;
|
||||||
unsigned j = i;
|
unsigned j = i;
|
||||||
|
|
||||||
|
fl = false;
|
||||||
|
|
||||||
for(; i<cn; ++i)
|
for(; i<cn; ++i)
|
||||||
{
|
{
|
||||||
if( i==j && cp[i]=='-' ) // allow the char following the e to be '-'
|
if( i==j && cp[i]=='-' ) // allow the char following the e to be '-'
|
||||||
@ -181,6 +191,7 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
|
|
||||||
if( isdigit(cp[i]) )
|
if( isdigit(cp[i]) )
|
||||||
{
|
{
|
||||||
|
++e;
|
||||||
++d;
|
++d;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -190,17 +201,42 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// an exp exists if digits follwed the 'e'
|
// an exp exists if digits follwed the 'e'
|
||||||
fl = d > 0;
|
fl = e > 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return i>1 && (n==1 || fl) ? i : 0;
|
// if at least one digit was found
|
||||||
|
if( d>0 )
|
||||||
|
{
|
||||||
|
// Note that this path allows a string w/o a decimal pt to trigger a match.
|
||||||
|
|
||||||
|
if(i<cn)
|
||||||
|
{
|
||||||
|
// if the real has a suffix
|
||||||
|
switch(cp[i])
|
||||||
|
{
|
||||||
|
case 'F':
|
||||||
|
case 'f':
|
||||||
|
p->attrFlags = cmSetFlag(p->attrFlags,kRealFloatLexFl);
|
||||||
|
++i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// match w/o suffix return
|
||||||
|
if( d>0 && (fl || n==1 || cmIsFlag(p->attrFlags,kRealFloatLexFl)) )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // no-match return
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr )
|
unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr )
|
||||||
{
|
{
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
bool signFl = false;
|
bool signFl = false;
|
||||||
|
|
||||||
for(; i<cn; ++i)
|
for(; i<cn; ++i)
|
||||||
{
|
{
|
||||||
if( i==0 && cp[i]=='-' )
|
if( i==0 && cp[i]=='-' )
|
||||||
@ -222,9 +258,35 @@ unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm
|
|||||||
//
|
//
|
||||||
// The current implementation recognizes all numeric strings
|
// The current implementation recognizes all numeric strings
|
||||||
// containing a decimal point as reals.
|
// containing a decimal point as reals.
|
||||||
|
|
||||||
|
|
||||||
return signFl && i==1 ? 0 : i;
|
// if no integer was found
|
||||||
|
if( (signFl && i==0) || i==0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
// check for suffix
|
||||||
|
if(i<cn )
|
||||||
|
{
|
||||||
|
|
||||||
|
switch(cp[i])
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
case 'U':
|
||||||
|
if( signFl )
|
||||||
|
_cmLexError(p,kSignErrorLexRC,"A signed integer has a 'u' or 'U' suffix.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->attrFlags = cmSetFlag(p->attrFlags,kIntUnsignedLexFl);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned _cmLexHexMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr )
|
unsigned _cmLexHexMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr )
|
||||||
@ -387,23 +449,6 @@ cmLexH cmLexInit( const cmChar_t* cp, unsigned cn, unsigned flags, cmRpt_t* rpt
|
|||||||
|
|
||||||
_cmLexSetTextBuffer( p, cp, cn );
|
_cmLexSetTextBuffer( p, cp, cn );
|
||||||
|
|
||||||
/*
|
|
||||||
p->cp = (cn==0) ? NULL : cp;
|
|
||||||
p->cn = (cp==NULL) ? 0 : cn;
|
|
||||||
|
|
||||||
p->ci = 0;
|
|
||||||
|
|
||||||
|
|
||||||
p->curTokenId = kErrorLexTId;
|
|
||||||
p->curTokenCharIdx = cmInvalidIdx;
|
|
||||||
p->curTokenCharCnt = 0;
|
|
||||||
|
|
||||||
p->curLine = 0;
|
|
||||||
p->curCol = 0;
|
|
||||||
p->nextLine = 0;
|
|
||||||
p->nextCol = 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
int init_mfn = 10;
|
int init_mfn = 10;
|
||||||
p->mfp = cmMemAllocZ( cmLexMatcher, init_mfn );
|
p->mfp = cmMemAllocZ( cmLexMatcher, init_mfn );
|
||||||
p->mfn = init_mfn;
|
p->mfn = init_mfn;
|
||||||
@ -537,70 +582,6 @@ cmRC_t cmLexSetFile( cmLexH h, const cmChar_t* fn )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
cmRC_t cmLexSetFile( cmLexH h, const cmChar_t* fn )
|
|
||||||
{
|
|
||||||
cmRC_t rc = kOkLexRC;
|
|
||||||
FILE* fp = NULL;
|
|
||||||
cmLex* p = _cmLexHandleToPtr(h);
|
|
||||||
unsigned n = 0;
|
|
||||||
|
|
||||||
assert( fn != NULL && p != NULL );
|
|
||||||
|
|
||||||
// open the file
|
|
||||||
if((fp = fopen(fn,"rb")) == NULL )
|
|
||||||
return _cmLexError(p,kFileOpenErrLexRC,"Unable to open the file:'%s'.",fn);
|
|
||||||
|
|
||||||
// seek to the end
|
|
||||||
if( fseek(fp,0,SEEK_END) != 0 )
|
|
||||||
{
|
|
||||||
rc= _cmLexError(p,kFileSeekErrLexRC,"Unable to seek to the end of '%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the length of the file
|
|
||||||
if( (n=ftell(fp)) == 0 )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kFileOpenErrLexRC,"The file '%s' appears to be empty.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rewind the file
|
|
||||||
if( fseek(fp,0,SEEK_SET) != 0 )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kFileSeekErrLexRC,"Unable to seek to the beginning of '%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate the text buffer
|
|
||||||
if((p->textBuf = cmMemResizeZ( char, p->textBuf, n+1)) == NULL )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kMemAllocErrLexRC,"Unable to allocate the text file buffer for:'%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the file into the text buffer
|
|
||||||
if( fread(p->textBuf,n,1,fp) != 1 )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kFileReadErrLexRC,"File read failed on:'%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((rc = _cmLexSetTextBuffer( p, p->textBuf, n )) != kOkLexRC )
|
|
||||||
goto errLabel;
|
|
||||||
|
|
||||||
errLabel:
|
|
||||||
|
|
||||||
// close the file
|
|
||||||
if( fclose(fp) != 0 )
|
|
||||||
{
|
|
||||||
rc = _cmLexError(p,kFileCloseErrLexRC,"File close failed on:'%s'.",fn);
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
cmLexMatcher* _cmLexFindUserToken( cmLex* p, unsigned id, const cmChar_t* tokenStr )
|
cmLexMatcher* _cmLexFindUserToken( cmLex* p, unsigned id, const cmChar_t* tokenStr )
|
||||||
{
|
{
|
||||||
@ -689,9 +670,9 @@ unsigned cmLexGetNextToken( cmLexH h )
|
|||||||
p->curTokenId = kErrorLexTId;
|
p->curTokenId = kErrorLexTId;
|
||||||
p->curTokenCharIdx = cmInvalidIdx;
|
p->curTokenCharIdx = cmInvalidIdx;
|
||||||
p->curTokenCharCnt = 0;
|
p->curTokenCharCnt = 0;
|
||||||
|
p->attrFlags = 0;
|
||||||
|
|
||||||
|
// try each matcher
|
||||||
// try each mater
|
|
||||||
for(; mi<p->mfi; ++mi)
|
for(; mi<p->mfi; ++mi)
|
||||||
if( p->mfp[mi].enableFl )
|
if( p->mfp[mi].enableFl )
|
||||||
{
|
{
|
||||||
@ -701,6 +682,7 @@ unsigned cmLexGetNextToken( cmLexH h )
|
|||||||
else
|
else
|
||||||
charCnt = p->mfp[mi].userPtr( p->cp + p->ci, p->cn - p->ci);
|
charCnt = p->mfp[mi].userPtr( p->cp + p->ci, p->cn - p->ci);
|
||||||
|
|
||||||
|
// notice if the matcher set the error code
|
||||||
if( cmErrLastRC(&p->err) != kOkLexRC )
|
if( cmErrLastRC(&p->err) != kOkLexRC )
|
||||||
return kErrorLexTId;
|
return kErrorLexTId;
|
||||||
|
|
||||||
@ -823,6 +805,19 @@ float cmLexTokenFloat( cmLexH h )
|
|||||||
double cmLexTokenDouble( cmLexH h )
|
double cmLexTokenDouble( cmLexH h )
|
||||||
{ return strtod( cmLexTokenText(h),NULL ); }
|
{ return strtod( cmLexTokenText(h),NULL ); }
|
||||||
|
|
||||||
|
|
||||||
|
bool cmLexTokenIsUnsigned( cmLexH h )
|
||||||
|
{
|
||||||
|
cmLex* p = _cmLexHandleToPtr(h);
|
||||||
|
return p->curTokenId == kIntLexTId && cmIsFlag(p->attrFlags,kIntUnsignedLexFl);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmLexTokenIsSinglePrecision( cmLexH h )
|
||||||
|
{
|
||||||
|
cmLex* p = _cmLexHandleToPtr(h);
|
||||||
|
return p->curTokenId == kRealLexTId && cmIsFlag(p->attrFlags,kRealFloatLexFl);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned cmLexCurrentLineNumber( cmLexH h )
|
unsigned cmLexCurrentLineNumber( cmLexH h )
|
||||||
{
|
{
|
||||||
cmLex* p = _cmLexHandleToPtr(h);
|
cmLex* p = _cmLexHandleToPtr(h);
|
||||||
|
15
cmLex.h
15
cmLex.h
@ -50,7 +50,8 @@ enum
|
|||||||
kMemAllocErrLexRC, //< 10 An attempted memory allocation failed
|
kMemAllocErrLexRC, //< 10 An attempted memory allocation failed
|
||||||
kEofRC, //< 11 The end of the input text was encountered (this is a normal condition not an error)
|
kEofRC, //< 11 The end of the input text was encountered (this is a normal condition not an error)
|
||||||
kInvalidLexTIdLexRC, //< 12 An invalid lex token id was encountered.
|
kInvalidLexTIdLexRC, //< 12 An invalid lex token id was encountered.
|
||||||
kInvalidLexRC //< 13 Sentinal value.
|
kSignErrorLexRC, //< 13 An signed integer has a 'u' or 'U' suffix."
|
||||||
|
kInvalidLexRC //< 1r Sentinal value.
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -119,15 +120,23 @@ unsigned cmLexTokenCharCount( cmLexH h );
|
|||||||
// Return the value of the current token as an integer.
|
// Return the value of the current token as an integer.
|
||||||
int cmLexTokenInt( cmLexH h );
|
int cmLexTokenInt( cmLexH h );
|
||||||
|
|
||||||
// Return the value of the current token as an integer.
|
// Return the value of the current token as an unsigned integer.
|
||||||
unsigned cmLexTokenUInt( cmLexH h );
|
unsigned cmLexTokenUInt( cmLexH h );
|
||||||
|
|
||||||
// Return the value of the current token as an integer.
|
// Return the value of the current token as a float.
|
||||||
float cmLexTokenFloat( cmLexH h );
|
float cmLexTokenFloat( cmLexH h );
|
||||||
|
|
||||||
// Return the value of the current token as a double.
|
// Return the value of the current token as a double.
|
||||||
double cmLexTokenDouble( cmLexH h );
|
double cmLexTokenDouble( cmLexH h );
|
||||||
|
|
||||||
|
// Return true if the current token is an int and it was suffixed
|
||||||
|
// with 'u' to indicate that it is unsigned.
|
||||||
|
bool cmLexTokenIsUnsigned( cmLexH h );
|
||||||
|
|
||||||
|
// Return true if the current token is a real and it was suffexed
|
||||||
|
// with 'f' to indicate that it is a single precision float.
|
||||||
|
bool cmLexTokenIsSinglePrecision( cmLexH h );
|
||||||
|
|
||||||
// Return the line number associated with the current token
|
// Return the line number associated with the current token
|
||||||
unsigned cmLexCurrentLineNumber( cmLexH h );
|
unsigned cmLexCurrentLineNumber( cmLexH h );
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user