/* This file is part of the KDE project Copyright (C) 2001 Andrea Rizzi Ulrich Kuettler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "basicelement.h" #include "elementtype.h" #include "sequenceparser.h" #include "symboltable.h" #include "textelement.h" KFORMULA_NAMESPACE_BEGIN SequenceParser::SequenceParser( const SymbolTable& t ) : tokenStart( 0 ), tokenEnd( 0 ), type( SEQUENCE ), binOpAllowed( false ), table( t ) { } void SequenceParser::setElementType( uint pos, ElementType* type ) { list.at( pos )->setElementType( type ); } ElementType* SequenceParser::parse( TQPtrList& elements ) { list = elements; return new SequenceType( this ); } void SequenceParser::nextToken() { tokenStart = tokenEnd; if ( tokenStart >= list.count() ) { type = END; return; } tokenEnd++; BasicElement* element = list.at( tokenStart ); type = element->getTokenType(); if ( type == SEPARATOR ) { if ( tokenEnd < list.count() ) { TQChar ch = getEndChar(); switch ( ch ) { case ',': case '>': case ';': type = NAME; tokenEnd++; break; default: readText(); } } } else if ( type == ORDINARY ) { readText(); } else if ( type == NUMBER ) { readNumber(); } if ( !binOpAllowed && ( type == BINOP ) ) { type = ORDINARY; } binOpAllowed = ( type == ORDINARY ) || ( type == NUMBER ) || ( type == NAME ) || ( type == ELEMENT ) || ( type == BRACKET ) || ( type == INNER ); //cerr << "SequenceParser::nextToken(): " << type << " " // << tokenStart << " " << tokenEnd << endl; } void SequenceParser::readNumber() { type = NUMBER; readDigits(); if ( tokenEnd < list.count()-1 ) { TQChar ch = getEndChar(); // Look for a dot. if ( ch == '.' ) { tokenEnd++; ch = getEndChar(); if ( ch.isNumber() ) { readDigits(); } // else { // tokenEnd--; // return; // } } // there might as well be an exponent if ( tokenEnd < list.count()-1 ) { BasicElement* element = list.at(tokenEnd); ch = getEndChar(); if ( ( element->getTokenType() == ORDINARY ) && ( ( ch == 'E' ) || ( ch == 'e' ) ) ) { tokenEnd++; ch = getEndChar(); // signs are allowed after the exponent if ( ( ( ch == '+' ) || ( ch == '-' ) ) && ( tokenEnd < list.count()-1 ) ) { tokenEnd++; ch = getEndChar(); if ( ch.isNumber() ) { readDigits(); } else { tokenEnd -= 2; return; } } else if ( ch.isNumber() ) { readDigits(); } else { tokenEnd--; } } } } } void SequenceParser::readDigits() { for ( ; tokenEnd < list.count(); tokenEnd++ ) { TQChar ch = getEndChar(); if ( !ch.isNumber() ) { break; } } } void SequenceParser::readText() { BasicElement* element = list.at( tokenStart ); TextElement* beginText = static_cast( element ); if ( beginText->isSymbol() || ( beginText->getCharacter() == '/' ) ) { return; } char format = beginText->format(); type = ORDINARY; for ( ; tokenEnd < list.count(); tokenEnd++ ) { element = list.at( tokenEnd ); TokenType tt = element->getTokenType(); if ( ( ( tt != ORDINARY ) || ( element->getCharacter() == '/' ) ) && ( tt != NUMBER ) ) { return; } if ( static_cast( element )->format() != format ) { return; } if ( static_cast( element )->isSymbol() ) { return; } } } TQChar SequenceParser::getEndChar() { BasicElement* element = list.at( tokenEnd ); return element->getCharacter(); } ElementType* SequenceParser::getPrimitive() { //cerr << "SequenceParser::getPrimitive(): " << type << " " // << tokenStart << " " << tokenEnd << endl; switch ( type ) { case ORDINARY: { // TQString text = getText(); // if ( table.contains( text ) || ( text == "\\quad" ) ) { // return new NameType( this, text ); // } // else { return new TextType( this ); // } } case NAME: return new NameType( this ); case NUMBER: return new NumberType( this ); case ELEMENT: return new ComplexElementType( this ); case INNER: return new InnerElementType( this ); case BINOP: return new OperatorType( this ); case RELATION: return new RelationType( this ); case PUNCTUATION: return new PunctuationType( this ); case BRACKET: return new BracketType( this ); case SEQUENCE: case SEPARATOR: case END: return 0; } return 0; } TQString SequenceParser::text() { TQString text; for ( uint i = tokenStart; i < tokenEnd; i++ ) { BasicElement* element = list.at( i ); text.append( element->getCharacter() ); } return text; } KFORMULA_NAMESPACE_END