Code Search for Developers
 
 
  

RingParser.C from Magnus at Krugle


Show RingParser.C syntax highlighted

// Copyright (C) 1995 The New York Group Theory Cooperative
// See magnus/doc/COPYRIGHT for the full notice.
//
// Contents: Implementations of classes RingEltParser, MatrixParser,
//           MonomialParser, PolynomialParser.
//
// Principal Author: Dmitry Bormotov
//
// Status: In development
//
// Usage:
//
// Discussion:
//
// Revision History:
//


#include "RingParser.h"
#include "Int2.h"


//------------------------------ RingEltParser ------------------------------//


template <class R>
void RingEltParser<R>::parseWhiteSpace( )
{
  char ch;

  // Flush whitespace & comments.
  do {
    if ( this->peekCh() == '#' )
      while ( this->peekCh() != '\n' ) {
	istr.get();
      }
    if ( ( ch = this->peekCh() ) == ' ' || ch == '\t' || ch == '\n' ) {
      ch = ' ';
      this->getCh();
    }
  } while ( ch == ' ' );
}

template <> Integer RingEltParser<Integer>::parseRingElt( Chars& errMesg )
{
  Integer result;
  
  if ( curToken !=  INT ) {
    this->parseError("expected an integer here");
    errMesg = this->parseErrorMessage;
    return result;
  }
  
  result = tokenInt;
//  this->getToken();
  return result;
}

template <> Int2 RingEltParser<Int2>::parseRingElt( Chars& errMesg )
{
  Int2 result;
  
  if ( curToken !=  INT ) {
    this->parseError("expected an integer here");
    errMesg = this->parseErrorMessage;
    return result;
  }
  
  result = tokenInt;
//  this->getToken();
  return result;
}

template <> Rational RingEltParser<Rational>::parseRingElt( Chars& errMesg )
{
  Integer numerator, denominator;
  
  if ( curToken !=  INT ) {
    this->parseError("expected an integer here");
    errMesg = this->parseErrorMessage;
    return Rational();
  }

  numerator = tokenInt;
/*
  this->getToken();

  if ( curToken ==  COMMA || curToken ==  RSQUARE ) {
    denominator = 1;
    return Rational(numerator, denominator);
  }

  if ( curToken !=  BAD || this->getCh() != '/' ) {
    this->parseError("expected a '/' here");
    errMesg = this->parseErrorMessage;
    return Rational();
  }
*/
  
  this->parseWhiteSpace();
  char ch = this->peekCh();
  if( ch == ',' || ch == ']' ) {
    denominator = 1;
//    this->getCh();
    return Rational(numerator, denominator);
  }

  if ( this->getCh() != '/' ) {
    this->parseError("expected a '/' here");
    errMesg = this->parseErrorMessage;
    return Rational();
  }
  
  this->getToken();

  if ( curToken !=  INT ) {
    this->parseError("expected an integer here");
    errMesg = this->parseErrorMessage;
    return Rational();
  }

  denominator = tokenInt;
//  this->getToken();

  if( denominator == 0 ) {
    this->parseError("invalid rational: zero denominator here");
    errMesg = this->parseErrorMessage;
    return Rational();
   }
  
  return Rational(numerator, denominator);
}


//----------------------------- MatrixParser --------------------------------//


template <class R>
VectorOf<R> MatrixParser<R>::parseMatrixRow( Chars& errMesg )
{
  VectorOf<R> result; 

  if ( this->curToken == INIT ) this->getToken();

  if ( this->curToken !=  LSQUARE ) {
    this->parseError("expected a '[' here");
    errMesg = this->parseErrorMessage;
    return result;
  }

  this->getToken();

  if ( this->curToken !=  INT ) {
    this->parseError("expected an integer here");
    errMesg = this->parseErrorMessage;
    return result;
  }

  while( true ) {

    R elem = this->parseRingElt(errMesg);
    this->getToken();
    
    if( errMesg.length() > 0 )
      return result;
    result.append(elem);
    
    if ( this->curToken ==  RSQUARE ) {
      this->getToken();
      return result;
    }
    
    if ( this->curToken !=  COMMA ) {
      this->parseError("expected a ',' here");
      errMesg = this->parseErrorMessage;
      return result;
    }
    
    this->getToken();
  }
}


template <class R>
void MatrixParser<R>::deleteMatrix( R ***M, int MSize )
{
  for( int i = 0; i < MSize; i++ )
    delete [] M[i];
  delete [] M; 
}


template <class R>
bool MatrixParser<R>::parseMatrix( Chars& errMesg, R ***M, int& MSize )
{
  int numOfRows = 0;
  
  if ( this->curToken == INIT ) this->getToken();
  
  if ( this->curToken !=  LSQUARE ) {
    this->parseError("expected a '[' here");
    errMesg = this->parseErrorMessage;
    return false;
  }

  this->getToken();
  bool bFirstIteration = true;
  
  while( true ) {
    VectorOf<R> row = parseMatrixRow(errMesg);
    if( errMesg.length() > 0 ) {
      if( !bFirstIteration )
	deleteMatrix(M, MSize);
      return false;
    }
    
    if( bFirstIteration ) {
      bFirstIteration = false;
      MSize = row.length();
      //@njz
      //      *M = new (R*)[MSize];
      *M = new R*[MSize];
      //
      for( int i = 0; i < MSize; i++ ) {
	(*M)[i] = new R[MSize];
      }
    }
    else
      if( row.length() != MSize ) {
	this->parseError("incorrect length of this row");
	errMesg = this->parseErrorMessage;
	deleteMatrix(M, MSize);
	return false;
      }

    if( numOfRows >= MSize) {
      this->parseError("too many rows here");
      errMesg = this->parseErrorMessage;
      deleteMatrix(M, MSize);
      return false;
    }
    
    for( int i = 0; i < MSize; i++ ) 
      (*M)[numOfRows][i] = row[i];

    numOfRows++;

    if( this->curToken == RSQUARE )
      if( numOfRows == MSize )
	return true;
      else {
	this->parseError("not enough rows here");
	errMesg = this->parseErrorMessage;
	deleteMatrix(M, MSize);
	return false;
      }
    else
      if( this->curToken == COMMA )
	this->getToken();
      else {
	this->parseError("expected ',' or ']' here");
	errMesg = this->parseErrorMessage;
	deleteMatrix(M, MSize);
	return false;
      }
  }
}

//--------------------------- MonomialParser -------------------------------//


template <class R>
Monomial<R> MonomialParser<R>::getMonomial( Chars& errMesg,
					    bool& isLastMonomial )
{
  int powersOfVars[maxNumberOfVariables];
  R coef = 1;
  int numOfVars = 0;
  isLastMonomial = false;

  for( int i = 0; i < maxNumberOfVariables; ++i )
    powersOfVars[i] = 0;

  this->parseWhiteSpace();
  char ch = this->peekCh();

  if( ch == '-' ) {
    this->getCh();
    coef = -1;
  }
  else
    if( ch == '+' )
      this->getCh();
  
  this->parseWhiteSpace();
  ch = tolower(this->peekCh());

  if ( ch >= '0' && ch <= '9' ) {
    this->getToken();

    coef *= this->parseRingElt(errMesg);
    if ( errMesg.length() > 0 ) {
      return Monomial<R>( );
    }

    this->parseWhiteSpace();

    if( ( ch = tolower(this->peekCh()) ) != 'x' ) {
      if( ch == ',') {
	this->getToken();
	isLastMonomial = true;
      }
      return Monomial<R>(coef);
    }
  }

  if( ch != 'x' ) {
    this->parseError("expected a 'x' here");
    errMesg = this->parseErrorMessage;
    return Monomial<R>( );
  }
  
  while( true ) {
    
    int index, power;
    this->getCh();
    this->getToken();
    
    if( this->curToken != INT || (index = this->tokenInt) <= 0 ) {
      this->parseError("expected a positive integer here");
      errMesg = this->parseErrorMessage;
      return Monomial<R>( );
    }
    
    this->parseWhiteSpace();
    ch = tolower(this->peekCh());

    if( ch == '^' ) {
      this->getCh();
      this->getToken();
      
      if( this->curToken !=  INT ) {
	this->parseError("expected an integer here");
	errMesg = this->parseErrorMessage;
	return Monomial<R>( );
      }
      power = this->tokenInt;

      this->parseWhiteSpace();
      ch = this->peekCh();
    }
    else
      power = 1;
    
    powersOfVars[index-1] += power;
    if( numOfVars < index )
      numOfVars = index;

    if( ch != 'x' ) {
      if( coef == R(0) )
	numOfVars = 0;
      if( ch == ',' ) {
	this->getToken();
	isLastMonomial = true;
      }
      return Monomial<R>(coef, numOfVars, powersOfVars);
    }
  }
}
/*
template <class R>
Monomial<R> MonomialParser<R>::parseMonomial( Chars& errMesg )
{
  bool isLastMonomial;
  return getMonomial(errMesg, isLastMonomial);
}
*/


//--------------------------- PolynomialParser ------------------------------//


template <class R>
Polynomial<R> PolynomialParser<R>::parsePolynomial( Chars& errMesg )
{
  Monomial<R> M;
  int koef = 1;
  bool isLastMonomial;
  Polynomial<R> result;

  while( true ) {
    M = this->getMonomial(errMesg, isLastMonomial);
    if ( errMesg.length() > 0 ) {
      return Polynomial<R>( );
    }

    if( M.getCoefficient() != R(0) )
      result.insert(M, M);
    
    if( isLastMonomial )
      return result;
    
    char ch = this->peekCh();
    if( ch != '+' && ch != '-' ) {
      this->parseError("expected a sign here");
      errMesg = this->parseErrorMessage;
      return Polynomial<R>( );
    }
  }
}



template class MatrixParser<Integer>;
template class MatrixParser<Rational>;
template class MonomialParser<Integer>;
template class MonomialParser<Rational>;
template class PolynomialParser<Integer>;
template class PolynomialParser<Rational>;

template class MonomialParser<Int2>;
template class PolynomialParser<Int2>;





See more files for this project here

Magnus

Magnus is a special purpose mathematical package for Infinite Group Theory computations

Project homepage: http://sourceforge.net/projects/magnus
Programming language(s): C,C++
License: other

  PBTree.C
  Polynomial.C
  RingParser.C