diff options
Diffstat (limited to 'lib/kformula/sequenceparser.cpp')
-rw-r--r-- | lib/kformula/sequenceparser.cpp | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/lib/kformula/sequenceparser.cpp b/lib/kformula/sequenceparser.cpp new file mode 100644 index 00000000..bbc2f0b1 --- /dev/null +++ b/lib/kformula/sequenceparser.cpp @@ -0,0 +1,241 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org> + Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de> + + 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<BasicElement>& 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<TextElement*>( 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<TextElement*>( element )->format() != format ) { + return; + } + if ( static_cast<TextElement*>( 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 |