Commit 0d3fd5d1 authored by dickelbeck's avatar dickelbeck

more specctra work

parent 1afb0498
......@@ -156,6 +156,7 @@ const static KEYWORD tokens[] = {
TOKDEF(host_cad),
TOKDEF(host_version),
TOKDEF(image),
TOKDEF(image_conductor),
TOKDEF(image_image),
TOKDEF(image_image_spacing),
TOKDEF(image_outline_clearance),
......@@ -464,6 +465,25 @@ int LINE_READER::ReadLine() throw (IOError)
//-----<LEXER>-------------------------------------------------------------
LEXER::LEXER( FILE* aFile, const wxString& aFilename ) :
reader( aFile, 4096 )
{
curTok = T_END;
stringDelimiter = '"';
filename = aFilename;
space_in_quoted_tokens = false;
// "start" should never change until we change the reader. The DSN
// format spec supports an include file mechanism but we can add that later
// using a std::stack to hold a stack of LINE_READERs to track nesting.
start = (char*) reader;
limit = start;
next = start;
}
int LEXER::findToken( const std::string& tok )
{
// convert to lower case once, this should be faster than using strcasecmp()
......@@ -485,16 +505,70 @@ int LEXER::findToken( const std::string& tok )
return -1;
}
wxString LEXER::GetTokenText( DSN_T aTok )
{
wxString ret;
if( aTok < 0 )
{
switch( aTok )
{
case T_QUOTE_DEF:
ret << _("'quoted text delimiter'");
break;
case T_DASH:
ret << wxT( "'-'" );
break;
case T_SYMBOL:
ret << _("'symbol'");
break;
case T_NUMBER:
ret << _("'number'");
break;
case T_RIGHT:
ret << wxT( "')'" );
break;
case T_LEFT:
ret << wxT( "'('" );
break;
case T_STRING:
ret << _("\"quoted string\"");
break;
case T_EOF:
ret << _("'end of file'");
break;
default:
;
}
}
else
{
ret << wxT("'") << CONV_FROM_UTF8( tokens[aTok].name ) << wxT("'");
}
return ret;
}
void LEXER::ThrowIOError( wxString aText, int charOffset ) throw (IOError)
{
aText << wxT(" ") << _("in file") << wxT(" \"") << filename
<< wxT("\" ") << _("on line") << wxT(" ") << reader.LineNumber()
<< wxT(" ") << _("at offset") << wxT(" ") << charOffset;
throw IOError( aText );
}
DSN_T LEXER::NextTok() throw (IOError)
{
char* head;
char* cur;
char* cur = next;
char* head = cur;
lastTok = curTok;
cur = next;
if( curTok != T_EOF )
{
if( cur >= limit )
......@@ -520,15 +594,27 @@ L_read:
// switching the string_quote character
if( lastTok == T_string_quote )
{
static const wxString errtxt( _("String delimiter must be a single character of ', \", or $"));
char cc = *cur;
switch( cc )
{
case '\'':
case '$':
case '"':
break;
default:
ThrowIOError( errtxt, CurOffset() );
}
curText.clear();
curText += *cur;
curText += cc;
head = cur+1;
if( head<limit && *head!=')' && *head!='(' && !isspace(*head) )
{
wxString errtxt(_("String delimiter char must be a single char") );
ThrowIOError( errtxt, cur-start+1 );
ThrowIOError( errtxt, CurOffset() );
}
curTok = T_QUOTE_DEF;
......@@ -578,17 +664,17 @@ L_read:
// a quoted string
else if( *cur == stringDelimiter )
{
++cur; // skip over the leading "
++cur; // skip over the leading delimiter: ",', or $
head = cur;
while( head<limit && *head!=stringDelimiter )
while( head<limit && !isStringTerminator( *head ) )
++head;
if( head >= limit )
{
wxString errtxt(_("Un-terminated delimited string") );
ThrowIOError( errtxt, cur-start+1 );
ThrowIOError( errtxt, CurOffset() );
}
curText.clear();
......@@ -627,8 +713,10 @@ L_read:
}
}
}
exit: // single point of exit
exit: // single point of exit
curOffset = cur - start;
next = head;
......@@ -640,7 +728,7 @@ exit: // single point of exit
#if defined(STANDALONE)
#if 0 && defined(STANDALONE)
// stand alone testing
......
......@@ -42,11 +42,10 @@ namespace DSN {
enum DSN_T {
// the first few are special (the uppercase ones)
T_QUOTE_DEF = -9,
T_DASH = -8,
T_SYMBOL = -7,
T_NUMBER = -6,
T_NONE = -5, // not a token
T_QUOTE_DEF = -8,
T_DASH = -7,
T_SYMBOL = -6,
T_NUMBER = -5,
T_RIGHT = -4, // right bracket, ')'
T_LEFT = -3, // left bracket, '('
T_STRING = -2, // a quoted string, stripped of the quotes
......@@ -157,6 +156,7 @@ enum DSN_T {
T_host_cad,
T_host_version,
T_image,
T_image_conductor,
T_image_image,
T_image_image_spacing,
T_image_outline_clearance,
......@@ -513,8 +513,11 @@ class LEXER
LINE_READER reader;
int stringDelimiter;
bool space_in_quoted_tokens; ///< blank spaces within quoted strings
wxString filename;
int lastTok; ///< curTok from previous NextTok() call.
int curOffset; ///< offset within current line of the current token
DSN_T curTok; ///< the current token obtained on last NextTok()
std::string curText; ///< the text of the current token
......@@ -543,24 +546,22 @@ class LEXER
*/
int findToken( const std::string& tok );
public:
LEXER( FILE* aFile, const wxString& aFilename ) :
reader( aFile, 4096 )
bool isStringTerminator( char cc )
{
curTok = T_NONE;
stringDelimiter = '"';
filename = aFilename;
if( !space_in_quoted_tokens && cc==' ' )
return true;
// "start" should never change until we change the reader. The DSN
// format spec supports an include file mechanism but we can add that later
// using a std::stack to hold a stack of LINE_READERs to track nesting.
start = (char*) reader;
if( cc == stringDelimiter )
return true;
limit = start;
next = start;
return false;
}
public:
LEXER( FILE* aFile, const wxString& aFilename );
/**
* Function SetStringDelimiter
* changes the string delimiter from the default " to some other character
......@@ -574,6 +575,19 @@ public:
stringDelimiter = aStringDelimiter;
return old;
}
/**
* Function SetSpaceInQuotedTokens
* changes the setting controlling whether a space in a quoted string is
* a terminator
*/
bool SetSpaceInQuotedTokens( bool val )
{
bool old = space_in_quoted_tokens;
space_in_quoted_tokens = val;
return old;
}
/**
* Function NextTok
......@@ -590,15 +604,11 @@ public:
* encapsulates the formatting of an error message which contains the exact
* location within the input file of a lexical error.
*/
void ThrowIOError( wxString aText, int charOffset ) throw (IOError)
{
aText << wxT(" ") << _("in file") << wxT(" \"") << filename
<< wxT("\" ") << _("on line") << wxT(" ") << reader.LineNumber()
<< wxT(" ") << _("at offset") << wxT(" ") << charOffset;
throw IOError( aText );
}
void ThrowIOError( wxString aText, int charOffset ) throw (IOError);
wxString GetTokenText( DSN_T aTok );
/**
* Function CurText
......@@ -618,6 +628,16 @@ public:
{
return curTok;
}
/**
* Function CurOffset
* returns the char offset within the current line, using a 1 based index.
* @return int - a one based index into the current line.
*/
int CurOffset()
{
return curOffset + 1;
}
};
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment