summaryrefslogtreecommitdiffstats
path: root/lib/kformula/sequenceparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kformula/sequenceparser.cpp')
-rw-r--r--lib/kformula/sequenceparser.cpp241
1 files changed, 241 insertions, 0 deletions
diff --git a/lib/kformula/sequenceparser.cpp b/lib/kformula/sequenceparser.cpp
new file mode 100644
index 000000000..bbc2f0b10
--- /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