sequenceparser.cc
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "basicelement.h"
00022 #include "elementtype.h"
00023 #include "sequenceparser.h"
00024 #include "symboltable.h"
00025 #include "textelement.h"
00026
00027
00028 KFORMULA_NAMESPACE_BEGIN
00029
00030
00031 SequenceParser::SequenceParser( const SymbolTable& t )
00032 : tokenStart( 0 ), tokenEnd( 0 ), type( SEQUENCE ),
00033 binOpAllowed( false ), table( t )
00034 {
00035 }
00036
00037
00038 void SequenceParser::setElementType( uint pos, ElementType* type )
00039 {
00040 list.at( pos )->setElementType( type );
00041 }
00042
00043
00044 ElementType* SequenceParser::parse( QPtrList<BasicElement>& elements )
00045 {
00046 list = elements;
00047 return new SequenceType( this );
00048 }
00049
00050
00051 void SequenceParser::nextToken()
00052 {
00053 tokenStart = tokenEnd;
00054 if ( tokenStart >= list.count() ) {
00055 type = END;
00056 return;
00057 }
00058 tokenEnd++;
00059 BasicElement* element = list.at( tokenStart );
00060 type = element->getTokenType();
00061 if ( type == SEPARATOR ) {
00062 if ( tokenEnd < list.count() ) {
00063 QChar ch = getEndChar();
00064 switch ( ch ) {
00065 case ',':
00066 case '>':
00067 case ';':
00068 type = NAME;
00069 tokenEnd++;
00070 break;
00071 default:
00072 readText();
00073 }
00074 }
00075 }
00076 else if ( type == ORDINARY ) {
00077 readText();
00078 }
00079 else if ( type == NUMBER ) {
00080 readNumber();
00081 }
00082 if ( !binOpAllowed && ( type == BINOP ) ) {
00083 type = ORDINARY;
00084 }
00085 binOpAllowed = ( type == ORDINARY ) || ( type == NUMBER ) || ( type == NAME ) ||
00086 ( type == ELEMENT ) || ( type == BRACKET ) || ( type == INNER );
00087
00088
00089
00090 }
00091
00092
00093 void SequenceParser::readNumber()
00094 {
00095 type = NUMBER;
00096 readDigits();
00097 if ( tokenEnd < list.count()-1 ) {
00098 QChar ch = getEndChar();
00099
00100
00101 if ( ch == '.' ) {
00102 tokenEnd++;
00103 ch = getEndChar();
00104 if ( ch.isNumber() ) {
00105 readDigits();
00106 }
00107
00108
00109
00110
00111 }
00112
00113
00114 if ( tokenEnd < list.count()-1 ) {
00115 BasicElement* element = list.at(tokenEnd);
00116 ch = getEndChar();
00117 if ( ( element->getTokenType() == ORDINARY ) &&
00118 ( ( ch == 'E' ) || ( ch == 'e' ) ) ) {
00119 tokenEnd++;
00120 ch = getEndChar();
00121
00122
00123 if ( ( ( ch == '+' ) || ( ch == '-' ) ) &&
00124 ( tokenEnd < list.count()-1 ) ) {
00125 tokenEnd++;
00126 ch = getEndChar();
00127 if ( ch.isNumber() ) {
00128 readDigits();
00129 }
00130 else {
00131 tokenEnd -= 2;
00132 return;
00133 }
00134 }
00135 else if ( ch.isNumber() ) {
00136 readDigits();
00137 }
00138 else {
00139 tokenEnd--;
00140 }
00141 }
00142 }
00143 }
00144 }
00145
00146
00147 void SequenceParser::readDigits()
00148 {
00149 for ( ; tokenEnd < list.count(); tokenEnd++ ) {
00150 QChar ch = getEndChar();
00151 if ( !ch.isNumber() ) {
00152 break;
00153 }
00154 }
00155 }
00156
00157
00158 void SequenceParser::readText()
00159 {
00160 BasicElement* element = list.at( tokenStart );
00161 TextElement* beginText = static_cast<TextElement*>( element );
00162 if ( beginText->isSymbol() ||
00163 ( beginText->getCharacter() == '/' ) ) {
00164 return;
00165 }
00166 char format = beginText->format();
00167 type = ORDINARY;
00168 for ( ; tokenEnd < list.count(); tokenEnd++ ) {
00169 element = list.at( tokenEnd );
00170 TokenType tt = element->getTokenType();
00171 if ( ( ( tt != ORDINARY ) ||
00172 ( element->getCharacter() == '/' ) ) &&
00173 ( tt != NUMBER ) ) {
00174 return;
00175 }
00176 if ( static_cast<TextElement*>( element )->format() != format ) {
00177 return;
00178 }
00179 if ( static_cast<TextElement*>( element )->isSymbol() ) {
00180 return;
00181 }
00182 }
00183 }
00184
00185 QChar SequenceParser::getEndChar()
00186 {
00187 BasicElement* element = list.at( tokenEnd );
00188 return element->getCharacter();
00189 }
00190
00191
00192 ElementType* SequenceParser::getPrimitive()
00193 {
00194
00195
00196 switch ( type ) {
00197 case ORDINARY: {
00198
00199
00200
00201
00202
00203 return new TextType( this );
00204
00205 }
00206 case NAME:
00207 return new NameType( this );
00208 case NUMBER:
00209 return new NumberType( this );
00210 case ELEMENT:
00211 return new ComplexElementType( this );
00212 case INNER:
00213 return new InnerElementType( this );
00214 case BINOP:
00215 return new OperatorType( this );
00216 case RELATION:
00217 return new RelationType( this );
00218 case PUNCTUATION:
00219 return new PunctuationType( this );
00220 case BRACKET:
00221 return new BracketType( this );
00222 case SEQUENCE:
00223 case SEPARATOR:
00224 case END:
00225 return 0;
00226 }
00227 return 0;
00228 }
00229
00230
00231 QString SequenceParser::text()
00232 {
00233 QString text;
00234 for ( uint i = tokenStart; i < tokenEnd; i++ ) {
00235 BasicElement* element = list.at( i );
00236 text.append( element->getCharacter() );
00237 }
00238 return text;
00239 }
00240
00241 KFORMULA_NAMESPACE_END
This file is part of the documentation for lib Library Version 1.4.2.