• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

C:/CVUT/diplomka/Automata_editor/sources/labelSyntaxChecker.cpp

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 // recursive descent ---> 
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; // EMPTY INPUT - generally ok, handle in client code!
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; // invert
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--; // go back in input
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 }

Generated on Tue Jan 4 2011 03:03:23 for Autoamata editor by  doxygen 1.7.0