00001 #include <SdlArs.h>
00002
00003 Lexer::Lexer( const string &aBuffer )
00004 : buffer( aBuffer ) , bufLen( aBuffer.length() ) , at( 0 ) , lineno( 0 )
00005 {
00006 }
00007
00008 const int Lexer::GetTopSymbol( void )
00009 {
00010 realConstant = false;
00011 constantStr.clear();
00012
00013 while( isSeparator() )
00014 at++;
00015
00016 return SkipComment();
00017 }
00018
00019 const bool Lexer::isSeparator( void )
00020 {
00021 if( at < bufLen && buffer.substr( at , 1 ).find_first_of( "\n\r\t " ) != string::npos )
00022 {
00023 if( buffer[at] == '\n' )
00024 lineno += 1;
00025 return true;
00026 }
00027 return false;
00028 }
00029
00030 const int Lexer::SkipComment( void )
00031 {
00032 if( at > bufLen )
00033 return -1;
00034 else if( at == bufLen )
00035 {
00036 at += 1;
00037 return EofId();
00038 }
00039 else if( (at + 2) < bufLen && buffer.substr( at , 2 ) == "//" )
00040 {
00041 at = buffer.find( '\n' , at );
00042
00043 return GetTopSymbol();
00044 }
00045 return LexNext();
00046 }
00047
00048 const int Lexer::LexNext( void )
00049 {
00050 for( map<string,int,greater<string> >::iterator it = symbol.begin() ; it != symbol.end() ; ++it )
00051 if( buffer.substr( at , it->first.length() ) == it->first )
00052 {
00053 constantStr = it->first;
00054 at += it->first.length();
00055 return it->second;
00056 }
00057
00058 if( isalpha( buffer[at] ) )
00059 return GetIdentifier();
00060 else if( isdigit( buffer[at] ) )
00061 return GetNumber();
00062
00063 return -1;
00064 }
00065
00066 const int Lexer::GetIdentifier( void )
00067 {
00068 while( isalnum( buffer[at] ) || buffer[at] == '_' )
00069 constantStr += buffer[at++];
00070
00071 return IdentifierId();
00072 }
00073
00074 const int Lexer::GetNumber( void )
00075 {
00076 while( isdigit( buffer[at] ) )
00077 constantStr += buffer[at++];
00078 if( buffer[at] == '.' )
00079 {
00080 at += 1;
00081 realConstant = true;
00082 constantStr += '.';
00083 while( isdigit( buffer[at] ) )
00084 constantStr += buffer[at++];
00085 }
00086 return NumberId();
00087 }
00088
00090 Interpret::Interpret( Lexer &SedLex )
00091 : duraLex( SedLex )
00092 {
00093 Initialize();
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 const bool Interpret::Run( void )
00106 {
00107 int ts = duraLex.GetTopSymbol();
00108
00109 while( ts != -1 )
00110 {
00111 switch( duraLex.atSr( back()->symbolId , ts ) )
00112 {
00113 default :
00114 case ' ' :
00115 { printf( "syntax error:\n" );
00116 for( deque<TreeNode*>::iterator it = begin() ; it != end() ; ++it )
00117 {
00118 const char *s = (*it)->constant.empty() ? "" : (*it)->constant.c_str();
00119 printf( "%s\t" , s );
00120 }
00121 printf( "\nwith terminal symbol: %s\n" , duraLex.GetConstant().c_str() );
00122 }
00123 return false;
00124
00125 case '=' :
00126 case '<' :
00127 ShiftRule( ts );
00128 ts = duraLex.GetTopSymbol();
00129 break;
00130
00131 case '>' :
00132 if( !ReduceRule( ts ) )
00133 return false;
00134 break;
00135 case '$' :
00136 return true;
00137 }
00138 }
00139 return true;
00140 }
00141
00142 void Interpret::Initialize( void )
00143 {
00144 clear();
00145 push_back( new TreeNode( duraLex.EofId() ) );
00146 }
00147
00148 void Interpret::ShiftRule( const int TopSymbol )
00149 {
00150 TreeNode *tn2 = back();
00151 back()->next = new TreeNode( TopSymbol , duraLex.GetConstant() );
00152 push_back( back()->next );
00153 tn2 = back();
00154 }
00155
00156 const bool Interpret::ReduceRule( const int TopSymbol )
00157 {
00158 TreeNode *tn = back();
00159 pop_back();
00160 TreeNode *tn2 = back();
00161 back()->next = 0;
00162 tn->next = tn->child;
00163 tn->child = back()->child;
00164 back()->child = tn;
00165
00166 return true;
00167 }