Go to the documentation of this file.00001 #include "constants.h"
00002
00003 #include "labelSyntaxChecker.h"
00004 #include "stringProcessor.h"
00005
00006 LabelSyntaxChecker::LabelSyntaxChecker(
00007 const ITransition::TCharSet &alphabet,
00008 const QString &alphabetSymb,
00009 const QString &epsilonSymb)
00010 : m_alphabet(alphabet), m_alphabetSymb(alphabetSymb), m_epsilonSymb(epsilonSymb)
00011 {
00012 DBGLOG(DBGPAR(alphabet));
00013 DBGLOG(DBGPAR(alphabetSymb));
00014 DBGLOG(DBGPAR(epsilonSymb));
00015 }
00016
00017 QString LabelSyntaxChecker::getReport()
00018 {
00019 return report.join("<br>");
00020 }
00021
00022 ITransition::TCharSet LabelSyntaxChecker::getCharacters()
00023 {
00024 return characters;
00025 }
00026
00027 LabelSyntaxChecker::ELabelTextPattern LabelSyntaxChecker::getPattern()
00028 {
00029 return pattern;
00030 }
00031
00032 StringProcessor::CharacterInfo LabelSyntaxChecker::nextToken()
00033 {
00034 Q_ASSERT(m_characterList.count() > m_idx);
00035 return m_characterList[m_idx++];
00036 }
00037
00038 bool LabelSyntaxChecker::hasNextToken()
00039 {
00040 return m_characterList.count() > m_idx;
00041 }
00042
00043 bool LabelSyntaxChecker::processCharacter(ITransition::TCharSet &charSet,
00044 const StringProcessor::CharacterInfo &charInfo)
00045 {
00046 if (!m_alphabet.contains(charInfo.character))
00047 {
00048 report << "Character isn't in alphabet.";
00049 return false;
00050 }
00051
00052 if (charInfo.modifier == StringProcessor::eBar || charInfo.modifier == StringProcessor::eOverline)
00053 {
00054 report << "Incorrect syntax, cannot be used overlined character here (" + charInfo.character + ").";
00055 return false;
00056 }
00057
00058 charSet << charInfo.character;
00059 return true;
00060 }
00061
00062 bool LabelSyntaxChecker::processBarredCharacter(ITransition::TCharSet &charSet,
00063 const StringProcessor::CharacterInfo &charInfo)
00064 {
00065 if (!m_alphabet.contains(charInfo.character))
00066 {
00067 report << "Character isn't in alphabet.";
00068 return false;
00069 }
00070
00071 if (charInfo.modifier != StringProcessor::eBar && charInfo.modifier != StringProcessor::eOverline)
00072 {
00073 report << "Incorrect syntax, expected overlined character.";
00074 return false;
00075 }
00076
00077 charSet << charInfo.character;
00078 return true;
00079 }
00080
00081
00082
00083 bool LabelSyntaxChecker::checkSyntax(const StringProcessor::TCharacterList &characterList)
00084 {
00085 report.clear();
00086 characters.clear();
00087 pattern = eEmptyPattern;
00088
00089 m_characterList = characterList;
00090 m_idx = 0;
00091 bool ok = true;
00092
00093 if (!hasNextToken()) return ok;
00094 StringProcessor::CharacterInfo charInfo = nextToken();
00095
00096 if (charInfo.character == m_epsilonSymb)
00097 {
00098 pattern = eEpsilonSymbPattern;
00099 characters = ITransition::TCharSet() << m_epsilonSymb;
00100 ok &= End();
00101 return ok;
00102 }
00103
00104 if (charInfo.character == m_alphabetSymb)
00105 {
00106 characters = m_alphabet;
00107 ok &= AlphabetOrAlphabetMinusPattern();
00108 return ok;
00109 }
00110
00111 if (charInfo.modifier == StringProcessor::eBar)
00112 {
00113 pattern = eBarPattern;
00114 m_idx--;
00115 ok &= BarPattern();
00116 if (!ok) return false;
00117 ok &= End();
00118 if (!ok) return false;
00119
00120 characters = m_alphabet - characters;
00121 if (characters.isEmpty())
00122 {
00123 report << "Incorrect definition, empty input isn't possible!";
00124 return false;
00125 }
00126
00127 return ok;
00128 }
00129
00130 m_idx--;
00131 pattern = eNormalPattern;
00132 ok &= NormalPattern(characters);
00133 if (!ok) return false;
00134 if (hasNextToken())
00135 {
00136 report << "info: Normal patter syntax is \"[character], [characeter], ...\"";
00137 }
00138 ok &= End();
00139 return ok;
00140 }
00141
00142 bool LabelSyntaxChecker::NormalPattern(ITransition::TCharSet &charSet)
00143 {
00144 if (!hasNextToken())
00145 {
00146 report << "Unexpected end of input.";
00147 return false;
00148 }
00149
00150 bool ok = true;
00151 StringProcessor::CharacterInfo charInfo = nextToken();
00152 ok &= processCharacter(charSet, charInfo);
00153 if (!ok) return false;
00154
00155 return NormalPatternNext(charSet);
00156 }
00157
00158 bool LabelSyntaxChecker::NormalPatternNext(ITransition::TCharSet &charSet)
00159 {
00160 bool ok = true;
00161 while (hasNextToken())
00162 {
00163 StringProcessor::CharacterInfo charInfo = nextToken();
00164 if (charInfo.character != ",")
00165 {
00166 m_idx--;
00167 return true;
00168 }
00169
00170 if (!hasNextToken())
00171 {
00172 report << "Unexpected end of input.";
00173 return false;
00174 }
00175
00176 charInfo = nextToken();
00177
00178 ok &= processCharacter(charSet, charInfo);
00179 if (!ok) return false;
00180 }
00181
00182 return true;
00183 }
00184
00185 bool LabelSyntaxChecker::BarPattern()
00186 {
00187 if (!hasNextToken())
00188 {
00189 report << "Unexpected end of input.";
00190 return false;
00191 }
00192
00193 bool ok = true;
00194 StringProcessor::CharacterInfo charInfo = nextToken();
00195 ok &= processBarredCharacter(characters, charInfo);
00196 if (!ok) return false;
00197
00198 return BarPatternNext();
00199 }
00200
00201 bool LabelSyntaxChecker::BarPatternNext()
00202 {
00203 bool ok = true;
00204 while (hasNextToken())
00205 {
00206 StringProcessor::CharacterInfo charInfo = nextToken();
00207 if (charInfo.character != ",")
00208 {
00209 report << "Unexpected character, expected ','.";
00210 return false;
00211 }
00212
00213 if (!hasNextToken())
00214 {
00215 report << "Unexpected end of input.";
00216 return false;
00217 }
00218
00219 charInfo = nextToken();
00220
00221 ok &= processBarredCharacter(characters, charInfo);
00222 if (!ok) return false;
00223 }
00224
00225 return true;
00226 }
00227
00228 bool LabelSyntaxChecker::AlphabetOrAlphabetMinusPattern()
00229 {
00230 if (!hasNextToken())
00231 {
00232 pattern = eAlphabetPattern;
00233 return End();
00234 }
00235
00236 pattern = eAlphabetMinusPattern;
00237
00238 StringProcessor::CharacterInfo charInfo = nextToken();
00239 if (charInfo.character != "-")
00240 {
00241 report << "Unexpected character, expected '-'.";
00242 return false;
00243 }
00244
00245 if (!hasNextToken())
00246 {
00247 report << "Unexpected end of input.";
00248 return false;
00249 }
00250
00251 charInfo = nextToken();
00252 if (charInfo.character != "\\{")
00253 {
00254 report << "Unexpected character, expected '\\{'.";
00255 return false;
00256 }
00257
00258 bool ok = true;
00259 ITransition::TCharSet minusCharacters;
00260 ok &= NormalPattern(minusCharacters);
00261 if (!ok) return false;
00262
00263 if (!hasNextToken())
00264 {
00265 report << "Unexpected end of input.";
00266 return false;
00267 }
00268
00269 charInfo = nextToken();
00270 if (charInfo.character != "\\}")
00271 {
00272 report << "Unexpected character, expected '\\}'.";
00273 return false;
00274 }
00275
00276 ok &= End();
00277 if (!ok) return false;
00278
00279 characters -= minusCharacters;
00280 if (characters.isEmpty())
00281 {
00282 report << "Incorrect definition, empty input isn't possible!";
00283 return false;
00284 }
00285
00286 return true;
00287 }
00288
00289 bool LabelSyntaxChecker::End()
00290 {
00291 if (hasNextToken())
00292 {
00293 report << "Unexpected character, expected end of input.";
00294 return false;
00295 }
00296 return true;
00297 }