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