sequenceparser.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org>
3 Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21#include "basicelement.h"
22#include "elementtype.h"
23#include "sequenceparser.h"
24#include "symboltable.h"
25#include "textelement.h"
26
27
28KFORMULA_NAMESPACE_BEGIN
29
30
31SequenceParser::SequenceParser( const SymbolTable& t )
32 : tokenStart( 0 ), tokenEnd( 0 ), type( SEQUENCE ),
33 binOpAllowed( false ), table( t )
34{
35}
36
37
39{
40 list.at( pos )->setElementType( type );
41}
42
43
44ElementType* SequenceParser::parse( TQPtrList<BasicElement>& elements )
45{
46 list = elements;
47 return new SequenceType( this );
48}
49
50
52{
53 tokenStart = tokenEnd;
54 if ( tokenStart >= list.count() ) {
55 type = END;
56 return;
57 }
58 tokenEnd++;
59 BasicElement* element = list.at( tokenStart );
60 type = element->getTokenType();
61 if ( type == SEPARATOR ) {
62 if ( tokenEnd < list.count() ) {
63 TQChar ch = getEndChar();
64 switch ( ch ) {
65 case ',':
66 case '>':
67 case ';':
68 type = NAME;
69 tokenEnd++;
70 break;
71 default:
72 readText();
73 }
74 }
75 }
76 else if ( type == ORDINARY ) {
77 readText();
78 }
79 else if ( type == NUMBER ) {
80 readNumber();
81 }
82 if ( !binOpAllowed && ( type == BINOP ) ) {
83 type = ORDINARY;
84 }
85 binOpAllowed = ( type == ORDINARY ) || ( type == NUMBER ) || ( type == NAME ) ||
86 ( type == ELEMENT ) || ( type == BRACKET ) || ( type == INNER );
87
88 //cerr << "SequenceParser::nextToken(): " << type << " "
89 // << tokenStart << " " << tokenEnd << endl;
90}
91
92
93void SequenceParser::readNumber()
94{
95 type = NUMBER;
96 readDigits();
97 if ( tokenEnd < list.count()-1 ) {
98 TQChar ch = getEndChar();
99
100 // Look for a dot.
101 if ( ch == '.' ) {
102 tokenEnd++;
103 ch = getEndChar();
104 if ( ch.isNumber() ) {
105 readDigits();
106 }
107// else {
108// tokenEnd--;
109// return;
110// }
111 }
112
113 // there might as well be an exponent
114 if ( tokenEnd < list.count()-1 ) {
115 BasicElement* element = list.at(tokenEnd);
116 ch = getEndChar();
117 if ( ( element->getTokenType() == ORDINARY ) &&
118 ( ( ch == 'E' ) || ( ch == 'e' ) ) ) {
119 tokenEnd++;
120 ch = getEndChar();
121
122 // signs are allowed after the exponent
123 if ( ( ( ch == '+' ) || ( ch == '-' ) ) &&
124 ( tokenEnd < list.count()-1 ) ) {
125 tokenEnd++;
126 ch = getEndChar();
127 if ( ch.isNumber() ) {
128 readDigits();
129 }
130 else {
131 tokenEnd -= 2;
132 return;
133 }
134 }
135 else if ( ch.isNumber() ) {
136 readDigits();
137 }
138 else {
139 tokenEnd--;
140 }
141 }
142 }
143 }
144}
145
146
147void SequenceParser::readDigits()
148{
149 for ( ; tokenEnd < list.count(); tokenEnd++ ) {
150 TQChar ch = getEndChar();
151 if ( !ch.isNumber() ) {
152 break;
153 }
154 }
155}
156
157
158void SequenceParser::readText()
159{
160 BasicElement* element = list.at( tokenStart );
161 TextElement* beginText = static_cast<TextElement*>( element );
162 if ( beginText->isSymbol() ||
163 ( beginText->getCharacter() == '/' ) ) {
164 return;
165 }
166 char format = beginText->format();
167 type = ORDINARY;
168 for ( ; tokenEnd < list.count(); tokenEnd++ ) {
169 element = list.at( tokenEnd );
170 TokenType tt = element->getTokenType();
171 if ( ( ( tt != ORDINARY ) ||
172 ( element->getCharacter() == '/' ) ) &&
173 ( tt != NUMBER ) ) {
174 return;
175 }
176 if ( static_cast<TextElement*>( element )->format() != format ) {
177 return;
178 }
179 if ( static_cast<TextElement*>( element )->isSymbol() ) {
180 return;
181 }
182 }
183}
184
185TQChar SequenceParser::getEndChar()
186{
187 BasicElement* element = list.at( tokenEnd );
188 return element->getCharacter();
189}
190
191
193{
194 //cerr << "SequenceParser::getPrimitive(): " << type << " "
195 // << tokenStart << " " << tokenEnd << endl;
196 switch ( type ) {
197 case ORDINARY: {
198// TQString text = getText();
199// if ( table.contains( text ) || ( text == "\\quad" ) ) {
200// return new NameType( this, text );
201// }
202// else {
203 return new TextType( this );
204// }
205 }
206 case NAME:
207 return new NameType( this );
208 case NUMBER:
209 return new NumberType( this );
210 case ELEMENT:
211 return new ComplexElementType( this );
212 case INNER:
213 return new InnerElementType( this );
214 case BINOP:
215 return new OperatorType( this );
216 case RELATION:
217 return new RelationType( this );
218 case PUNCTUATION:
219 return new PunctuationType( this );
220 case BRACKET:
221 return new BracketType( this );
222 case SEQUENCE:
223 case SEPARATOR:
224 case END:
225 return 0;
226 }
227 return 0;
228}
229
230
232{
233 TQString text;
234 for ( uint i = tokenStart; i < tokenEnd; i++ ) {
235 BasicElement* element = list.at( i );
236 text.append( element->getCharacter() );
237 }
238 return text;
239}
240
241KFORMULA_NAMESPACE_END
Basis of every formula element.
virtual TQChar getCharacter() const
virtual TokenType getTokenType() const
Basis of all types.
Definition elementtype.h:52
A recognized name.
A range of elements that make up a number.
void nextToken()
Reads the next token.
ElementType * parse(TQPtrList< BasicElement > &elements)
ElementType * getPrimitive()
void setElementType(uint pos, ElementType *type)
Tells the element about its new type.
The token that belongs to a sequence.
The symbol table.
Definition symboltable.h:77
An element that represents one char.
Definition textelement.h:37
virtual TQChar getCharacter() const
Definition textelement.h:65
bool isSymbol() const
Moves the cursor away from the given child.
A text element that doesn't belong to an name.