You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/lib/kformula/sequenceparser.cc

242 lines
6.3 KiB

/* 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