diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | ce599e4f9f94b4eb00c1b5edb85bce5431ab3df2 (patch) | |
tree | d3bb9f5d25a2dc09ca81adecf39621d871534297 /kalzium/src/parser.cpp | |
download | tdeedu-ce599e4f9f94b4eb00c1b5edb85bce5431ab3df2.tar.gz tdeedu-ce599e4f9f94b4eb00c1b5edb85bce5431ab3df2.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeedu@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kalzium/src/parser.cpp')
-rw-r--r-- | kalzium/src/parser.cpp | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/kalzium/src/parser.cpp b/kalzium/src/parser.cpp new file mode 100644 index 00000000..19364c73 --- /dev/null +++ b/kalzium/src/parser.cpp @@ -0,0 +1,217 @@ +/*************************************************************************** + copyright : (C) 2005 by Inge Wallin + email : inge@lysator.liu.se + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include <ctype.h> + +#include <kdebug.h> + +#include "parser.h" + + +Parser::Parser() +{ + start(QString::null); +} + + +Parser::Parser(const QString& _str) +{ + start(_str); +} + + +Parser::~Parser() +{ +} + + +void +Parser::start(const QString& _str) +{ + m_str = _str; + + if (_str.isNull()) { + m_index = -1; + m_nextChar = -1; + m_nextToken = -1; + } + else { + m_index = 0; + m_nextChar = m_str.at(0).latin1(); + getNextToken(); + } +} + + +// ---------------------------------------------------------------- + + +// Skip whitespace, and try to parse the following characters as an int. +// +// Return true if successful. + +bool +Parser::parseInt(int *_result) +{ + int sign = 1; + + skipWhitespace(); + + if (m_nextChar == '-') { + sign = -1; + getNextChar(); + } + + if (!isdigit(m_nextChar)) + return false; + + int result = 0; + while (isdigit(m_nextChar)) { + result = result * 10 + (m_nextChar - '0'); + getNextChar(); + } + + *_result = sign * result; + return true; +} + + +// Skip whitespace, and try to parse the following characters as a +// simple float of the type -?[0-9]+'.'?[0-9]* +// +// Return true if successful. + +bool +Parser::parseSimpleFloat(double *_result) +{ + double sign = 1.0; + + skipWhitespace(); + if (m_nextChar == '-') { + sign = -1.0; + getNextChar(); + } + + if (!isdigit(m_nextChar)) + return false; + + double result = 0.0; + + // The integer. + while (isdigit(m_nextChar)) { + result = result * 10.0 + (double) (m_nextChar - '0'); + getNextChar(); + } + *_result = result; + + if (m_nextChar != '.' || !isdigit(getNextChar())) { + *_result = sign * result; + return true; + } + + double decimal = 0.1; + while (isdigit(m_nextChar)) { + result += decimal * (double) (m_nextChar - '0'); + decimal /= 10.0; + getNextChar(); + } + + *_result = sign * result; + return true; +} + + +// ---------------------------------------------------------------- +// protected methods + + +int +Parser::getNextChar() +{ + if (m_index == -1) + return -1; + + // If end of string, then reset the parser. + if (m_index == (int) m_str.length()) { + m_index = -1; + m_nextChar = -1; + } + else + m_nextChar = m_str.at(++m_index).latin1(); + + // Take care of null-terminated strings. + if (m_nextChar == 0) { + m_index = -1; + m_nextChar = -1; + } + + //kdDebug() << "Parser::getNextChar(): char = " << m_nextChar << endl; + + return m_nextChar; +} + + +int +Parser::skipWhitespace() +{ + while (QChar(m_nextChar).isSpace()) + getNextChar(); + + return m_nextChar; +} + + +// Get the next token. This corresponds to the lexical analyzer of a +// standard parser, e.g as generated by lex. +// +// This basic parser supports integers and simple +// floats. Reimplement this method to extend it. + +int +Parser::getNextToken() +{ + int saveIndex = m_index; + + skipWhitespace(); + if (isdigit(nextChar())) { + // At this point we know that there is a valid number in the + // string. The only question now, is whether it is an int or a + // float. + + parseInt(&m_intVal); + + skipWhitespace(); + if (nextChar() == '.') { + m_index = saveIndex; + + // No need to check since we already know it is correct. + (void) parseSimpleFloat(&m_floatVal); + m_nextToken = FLOAT_TOKEN; + } + else + m_nextToken = INT_TOKEN; + } + + else if (nextChar() != -1) { + // Any character. + m_nextToken = nextChar(); + getNextChar(); + } + + else + // End of string. + m_nextToken = -1; + + return m_nextToken; +} |