factor some pioneering code into a the stable building block class DSNLEXER, generalize expected valued for name and value within the template field parser.
This commit is contained in:
parent
1ff2b5596f
commit
0361ad6a55
|
@ -192,6 +192,18 @@ wxString DSNLEXER::GetTokenString( int aTok )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DSNLEXER::IsSymbol( int aTok )
|
||||||
|
{
|
||||||
|
// This is static and not inline to reduce code space.
|
||||||
|
|
||||||
|
// if aTok is >= 0, then it is a coincidental match to a keyword.
|
||||||
|
return aTok==DSN_SYMBOL
|
||||||
|
|| aTok==DSN_STRING
|
||||||
|
|| aTok>=0
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DSNLEXER::ThrowIOError( wxString aText, int charOffset ) throw (IOError)
|
void DSNLEXER::ThrowIOError( wxString aText, int charOffset ) throw (IOError)
|
||||||
{
|
{
|
||||||
// append to aText, do not overwrite
|
// append to aText, do not overwrite
|
||||||
|
@ -235,6 +247,39 @@ void DSNLEXER::Unexpected( const wxString& text ) throw( IOError )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DSNLEXER::NeedLEFT() throw( IOError )
|
||||||
|
{
|
||||||
|
int tok = NextTok();
|
||||||
|
if( tok != DSN_LEFT )
|
||||||
|
Expecting( DSN_LEFT );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DSNLEXER::NeedRIGHT() throw( IOError )
|
||||||
|
{
|
||||||
|
int tok = NextTok();
|
||||||
|
if( tok != DSN_RIGHT )
|
||||||
|
Expecting( DSN_RIGHT );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DSNLEXER::NeedSYMBOL() throw( IOError )
|
||||||
|
{
|
||||||
|
int tok = NextTok();
|
||||||
|
if( !IsSymbol( tok ) )
|
||||||
|
Expecting( DSN_SYMBOL );
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DSNLEXER::NeedSYMBOLorNUMBER() throw( IOError )
|
||||||
|
{
|
||||||
|
int tok = NextTok();
|
||||||
|
if( !IsSymbol( tok ) && tok!=DSN_NUMBER )
|
||||||
|
Expecting( _("symbol|number") );
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function isspace
|
* Function isspace
|
||||||
* strips the upper bits of the int to ensure the value passed to ::isspace() is
|
* strips the upper bits of the int to ensure the value passed to ::isspace() is
|
||||||
|
|
|
@ -50,35 +50,29 @@ void TEMPLATE_FIELDNAME::Parse( DSNLEXER* in ) throw( IOError )
|
||||||
{
|
{
|
||||||
TFIELD_T tok;
|
TFIELD_T tok;
|
||||||
|
|
||||||
if( (tok = (TFIELD_T) in->NextTok()) != T_LEFT )
|
in->NeedLEFT(); // begin (name ...)
|
||||||
in->Expecting( T_LEFT );
|
|
||||||
|
|
||||||
if( (tok = (TFIELD_T) in->NextTok()) != T_name )
|
if( (tok = (TFIELD_T) in->NextTok()) != T_name )
|
||||||
in->Expecting( T_name );
|
in->Expecting( T_name );
|
||||||
|
|
||||||
if( (tok = (TFIELD_T) in->NextTok()) != T_SYMBOL && tok!=T_STRING )
|
in->NeedSYMBOLorNUMBER();
|
||||||
in->Expecting( _("field's name") );
|
|
||||||
|
|
||||||
m_Name = CONV_FROM_UTF8( in->CurText() );
|
m_Name = CONV_FROM_UTF8( in->CurText() );
|
||||||
|
|
||||||
if( (tok = (TFIELD_T) in->NextTok()) != T_RIGHT )
|
in->NeedRIGHT(); // end (name ...)
|
||||||
in->Expecting( T_RIGHT );
|
|
||||||
|
|
||||||
while( (tok = (TFIELD_T) in->NextTok() ) != T_RIGHT && tok != T_EOF )
|
while( (tok = (TFIELD_T) in->NextTok() ) != T_RIGHT && tok != T_EOF )
|
||||||
{
|
{
|
||||||
|
// "visible" has no '(' prefix, "value" does, so T_LEFT is optional.
|
||||||
if( tok == T_LEFT )
|
if( tok == T_LEFT )
|
||||||
tok = (TFIELD_T) in->NextTok();
|
tok = (TFIELD_T) in->NextTok();
|
||||||
|
|
||||||
switch( tok )
|
switch( tok )
|
||||||
{
|
{
|
||||||
case T_value:
|
case T_value:
|
||||||
if( (tok = (TFIELD_T) in->NextTok()) != T_SYMBOL && tok!=T_STRING )
|
in->NeedSYMBOLorNUMBER();
|
||||||
in->Expecting( _("field's value") );
|
|
||||||
|
|
||||||
m_Value = CONV_FROM_UTF8( in->CurText() );
|
m_Value = CONV_FROM_UTF8( in->CurText() );
|
||||||
|
in->NeedRIGHT();
|
||||||
if( (tok = (TFIELD_T) in->NextTok()) != T_RIGHT )
|
|
||||||
in->Expecting( T_RIGHT );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_visible:
|
case T_visible:
|
||||||
|
@ -86,7 +80,7 @@ void TEMPLATE_FIELDNAME::Parse( DSNLEXER* in ) throw( IOError )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
in->Unexpected( CONV_FROM_UTF8( in->CurText() ) );
|
in->Expecting( wxT( "value|visible" ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,10 +208,9 @@ public:
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function NextTok
|
* Function NextTok
|
||||||
* returns the next token found in the input file or T_EOF when reaching
|
* returns the next token found in the input file or DSN_EOF when reaching
|
||||||
* the end of file. Users should wrap this function to return an enum
|
* the end of file. Users should wrap this function to return an enum
|
||||||
* to aid in grammar debugging while running under a debugger, but leave
|
* to aid in grammar debugging while running under a debugger, but leave
|
||||||
* this lower level function returning an int (so the enum does not collide
|
* this lower level function returning an int (so the enum does not collide
|
||||||
|
@ -221,6 +220,13 @@ public:
|
||||||
*/
|
*/
|
||||||
int NextTok() throw (IOError);
|
int NextTok() throw (IOError);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function IsSymbol
|
||||||
|
* tests a token to see if it is a symbol. This means it cannot be a
|
||||||
|
* special delimiter character such as DSN_LEFT, DSN_RIGHT, DSN_QUOTE, etc. It may
|
||||||
|
* however, coincidentally match a keyword and still be a symbol.
|
||||||
|
*/
|
||||||
|
static bool IsSymbol( int aTok );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ThrowIOError
|
* Function ThrowIOError
|
||||||
|
@ -264,6 +270,42 @@ public:
|
||||||
*/
|
*/
|
||||||
void Unexpected( const wxString& aErrorMsg ) throw( IOError );
|
void Unexpected( const wxString& aErrorMsg ) throw( IOError );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function NeedLEFT
|
||||||
|
* calls NextTok() and then verifies that the token read in is a DSN_LEFT.
|
||||||
|
* If it is not, an IOError is thrown.
|
||||||
|
* @throw IOError, if the next token is not a DSN_LEFT
|
||||||
|
*/
|
||||||
|
void NeedLEFT() throw( IOError );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function NeedRIGHT
|
||||||
|
* calls NextTok() and then verifies that the token read in is a DSN_RIGHT.
|
||||||
|
* If it is not, an IOError is thrown.
|
||||||
|
* @throw IOError, if the next token is not a DSN_RIGHT
|
||||||
|
*/
|
||||||
|
void NeedRIGHT() throw( IOError );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function NeedSYMBOL
|
||||||
|
* calls NextTok() and then verifies that the token read in
|
||||||
|
* satisfies bool IsSymbol().
|
||||||
|
* If not, an IOError is thrown.
|
||||||
|
* @return int - the actual token read in.
|
||||||
|
* @throw IOError, if the next token does not satisfy IsSymbol()
|
||||||
|
*/
|
||||||
|
int NeedSYMBOL() throw( IOError );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function NeedSYMBOLorNUMBER
|
||||||
|
* calls NextTok() and then verifies that the token read in
|
||||||
|
* satisfies bool IsSymbol() or tok==DSN_NUMBER.
|
||||||
|
* If not, an IOError is thrown.
|
||||||
|
* @return int - the actual token read in.
|
||||||
|
* @throw IOError, if the next token does not satisfy the above test
|
||||||
|
*/
|
||||||
|
int NeedSYMBOLorNUMBER() throw( IOError );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetTokenText
|
* Function GetTokenText
|
||||||
* returns the C string representation of a DSN_T value.
|
* returns the C string representation of a DSN_T value.
|
||||||
|
|
|
@ -547,21 +547,12 @@ void SPECCTRA_DB::ThrowIOError( const wxChar* fmt, ... ) throw( IOError )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SPECCTRA_DB::expecting( DSN_T aTok ) throw( IOError )
|
|
||||||
{
|
|
||||||
lexer->Expecting( aTok );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPECCTRA_DB::expecting( const char* text ) throw( IOError )
|
void SPECCTRA_DB::expecting( const char* text ) throw( IOError )
|
||||||
{
|
{
|
||||||
wxString errText = CONV_FROM_UTF8( text );
|
wxString errText = CONV_FROM_UTF8( text );
|
||||||
lexer->Expecting( errText );
|
lexer->Expecting( errText );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPECCTRA_DB::unexpected( DSN_T aTok ) throw( IOError )
|
|
||||||
{
|
|
||||||
lexer->Unexpected( aTok );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPECCTRA_DB::unexpected( const char* text ) throw( IOError )
|
void SPECCTRA_DB::unexpected( const char* text ) throw( IOError )
|
||||||
{
|
{
|
||||||
|
@ -576,47 +567,6 @@ DSN_T SPECCTRA_DB::nextTok()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SPECCTRA_DB::isSymbol( DSN_T aTok )
|
|
||||||
{
|
|
||||||
// if aTok is >= 0, then it might be a coincidental match to a keyword.
|
|
||||||
return aTok==T_SYMBOL
|
|
||||||
|| aTok==T_STRING
|
|
||||||
|| aTok>=0
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SPECCTRA_DB::needLEFT() throw( IOError )
|
|
||||||
{
|
|
||||||
DSN_T tok = nextTok();
|
|
||||||
if( tok != T_LEFT )
|
|
||||||
expecting( T_LEFT );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPECCTRA_DB::needRIGHT() throw( IOError )
|
|
||||||
{
|
|
||||||
DSN_T tok = nextTok();
|
|
||||||
if( tok != T_RIGHT )
|
|
||||||
expecting( T_RIGHT );
|
|
||||||
}
|
|
||||||
|
|
||||||
DSN_T SPECCTRA_DB::needSYMBOL() throw( IOError )
|
|
||||||
{
|
|
||||||
DSN_T tok = nextTok();
|
|
||||||
if( !isSymbol( tok ) )
|
|
||||||
expecting( T_SYMBOL );
|
|
||||||
return tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
DSN_T SPECCTRA_DB::needSYMBOLorNUMBER() throw( IOError )
|
|
||||||
{
|
|
||||||
DSN_T tok = nextTok();
|
|
||||||
if( !isSymbol( tok ) && tok!=T_NUMBER )
|
|
||||||
expecting( "symbol|number" );
|
|
||||||
return tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id ) throw( IOError )
|
void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id ) throw( IOError )
|
||||||
{
|
{
|
||||||
DSN_T tok;
|
DSN_T tok;
|
||||||
|
|
|
@ -4039,15 +4039,16 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
||||||
*/
|
*/
|
||||||
DSN_T nextTok();
|
DSN_T nextTok();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function isSymbol
|
* Function isSymbol
|
||||||
* tests a token to see if it is a symbol. This means it cannot be a
|
* tests a token to see if it is a symbol. This means it cannot be a
|
||||||
* special delimiter character such as T_LEFT, T_RIGHT, T_QUOTE, etc. It may
|
* special delimiter character such as T_LEFT, T_RIGHT, T_QUOTE, etc. It may
|
||||||
* however, coincidentally match a keyword and still be a symbol.
|
* however, coincidentally match a keyword and still be a symbol.
|
||||||
*/
|
*/
|
||||||
static bool isSymbol( DSN_T aTok );
|
static bool isSymbol( DSN_T aTok )
|
||||||
|
{
|
||||||
|
return DSNLEXER::IsSymbol( aTok );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function needLEFT
|
* Function needLEFT
|
||||||
|
@ -4055,7 +4056,10 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
||||||
* If it is not, an IOError is thrown.
|
* If it is not, an IOError is thrown.
|
||||||
* @throw IOError, if the next token is not a T_LEFT
|
* @throw IOError, if the next token is not a T_LEFT
|
||||||
*/
|
*/
|
||||||
void needLEFT() throw( IOError );
|
void needLEFT() throw( IOError )
|
||||||
|
{
|
||||||
|
lexer->NeedLEFT();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function needRIGHT
|
* Function needRIGHT
|
||||||
|
@ -4063,7 +4067,10 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
||||||
* If it is not, an IOError is thrown.
|
* If it is not, an IOError is thrown.
|
||||||
* @throw IOError, if the next token is not a T_RIGHT
|
* @throw IOError, if the next token is not a T_RIGHT
|
||||||
*/
|
*/
|
||||||
void needRIGHT() throw( IOError );
|
void needRIGHT() throw( IOError )
|
||||||
|
{
|
||||||
|
lexer->NeedRIGHT();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function needSYMBOL
|
* Function needSYMBOL
|
||||||
|
@ -4073,7 +4080,10 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
||||||
* @return DSN_T - the actual token read in.
|
* @return DSN_T - the actual token read in.
|
||||||
* @throw IOError, if the next token does not satisfy isSymbol()
|
* @throw IOError, if the next token does not satisfy isSymbol()
|
||||||
*/
|
*/
|
||||||
DSN_T needSYMBOL() throw( IOError );
|
DSN_T needSYMBOL() throw( IOError )
|
||||||
|
{
|
||||||
|
return (DSN_T) lexer->NeedSYMBOL();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function needSYMBOLorNUMBER
|
* Function needSYMBOLorNUMBER
|
||||||
|
@ -4083,7 +4093,10 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
||||||
* @return DSN_T - the actual token read in.
|
* @return DSN_T - the actual token read in.
|
||||||
* @throw IOError, if the next token does not satisfy the above test
|
* @throw IOError, if the next token does not satisfy the above test
|
||||||
*/
|
*/
|
||||||
DSN_T needSYMBOLorNUMBER() throw( IOError );
|
DSN_T needSYMBOLorNUMBER() throw( IOError )
|
||||||
|
{
|
||||||
|
return (DSN_T) lexer->NeedSYMBOLorNUMBER();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function readCOMPnPIN
|
* Function readCOMPnPIN
|
||||||
|
@ -4127,9 +4140,15 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
|
||||||
* @param int is the token type which was expected at the current input location.
|
* @param int is the token type which was expected at the current input location.
|
||||||
* @throw IOError with the location within the input file of the problem.
|
* @throw IOError with the location within the input file of the problem.
|
||||||
*/
|
*/
|
||||||
void expecting( DSN_T aTok ) throw( IOError );
|
void expecting( DSN_T aTok ) throw( IOError )
|
||||||
|
{
|
||||||
|
lexer->Expecting( aTok );
|
||||||
|
}
|
||||||
|
void unexpected( DSN_T aTok ) throw( IOError )
|
||||||
|
{
|
||||||
|
lexer->Unexpected( aTok );
|
||||||
|
}
|
||||||
void expecting( const char* text ) throw( IOError );
|
void expecting( const char* text ) throw( IOError );
|
||||||
void unexpected( DSN_T aTok ) throw( IOError );
|
|
||||||
void unexpected( const char* text ) throw( IOError );
|
void unexpected( const char* text ) throw( IOError );
|
||||||
|
|
||||||
void doPCB( PCB* growth ) throw(IOError);
|
void doPCB( PCB* growth ) throw(IOError);
|
||||||
|
|
Loading…
Reference in New Issue