initial import
[vym] / parser.cpp
diff --git a/parser.cpp b/parser.cpp
new file mode 100644 (file)
index 0000000..523ac12
--- /dev/null
@@ -0,0 +1,349 @@
+#include "parser.h"
+
+#include <QRegExp>
+#include <iostream>
+
+using namespace std;
+
+Parser::Parser()
+{
+       initParser();
+}
+
+void Parser::initParser()
+{
+       initAtom();
+       current=-1;
+}
+
+void Parser::initAtom()
+{
+       atom="";
+       com="";
+       paramList.clear();
+       resetError();
+}
+
+void Parser::parseAtom (QString s)
+{
+       initAtom();
+       atom=s;
+       QRegExp re;
+       int pos;
+
+       // Strip WS at beginning
+       re.setPattern ("\\w");
+       re.setMinimal (true);
+       pos=re.search (atom);
+       if (pos>=0)
+               s=s.right(s.length()-pos);
+
+       // Get command
+       re.setPattern ("\\b(.*)(\\s|\\()");
+       pos=re.search (s);
+       if (pos>=0)
+               com=re.cap(1);
+
+       // Get parameters
+       paramList.clear();
+       re.setPattern ("\\((.*)\\)");
+       pos=re.search (s);
+       //cout << "  s="<<qPrintable(s)<<endl;
+       //cout << "com="<<qPrintable(com)<<"  pos="<<pos<<endl<<endl;
+       if (pos>=0)
+       {
+               QString s=re.cap(1);
+               QString a;
+               bool inquote=false;
+               pos=0;
+               if (!s.isEmpty())
+               {
+                       while (pos<s.length())
+                       {
+                               if (s.at(pos)=='\"') 
+                               {
+                                       if (inquote)
+                                               inquote=false;
+                                       else    
+                                               inquote=true;
+                               }
+
+                               if (s.at(pos)==',' && !inquote)
+                               {
+                                       a=s.left(pos);
+                                       paramList.append(a);
+                                       s=s.right(s.length()-pos-1);
+                                       pos=0;
+                               } else
+                                       pos++;
+                               
+                       }
+                       paramList.append (s);
+               }       
+       }       
+}
+
+QString Parser::getAtom()
+{
+       return atom;
+}
+
+QString Parser::getCommand()
+{
+       return com;
+}
+
+QStringList Parser::getParameters()
+{
+       return paramList;
+}
+
+int Parser::parCount()
+{
+       return paramList.count();
+}
+
+
+QString Parser::errorMessage()
+{
+       QString l;
+       switch (errLevel)
+       {
+               case NoError: l="No Error";
+               case Warning: l="Warning";
+               case Aborted: l="Aborted";
+       }
+       return QString ("Error Level: %1\n    Command: %2\nDescription: %3")
+               .arg(l).arg(com).arg(errDescription);
+}
+
+QString Parser::errorDescription()
+{
+       return errDescription;
+}
+
+ErrorLevel Parser::errorLevel()
+{
+       return errLevel;
+}
+
+void Parser::setError(ErrorLevel level, const QString &description)
+{
+       errDescription=description;
+       errLevel=level;
+}
+
+void Parser::resetError ()
+{
+       errMessage="";
+       errDescription="";
+       errLevel=NoError;
+}
+
+
+bool Parser::checkParCount (QList <int> plist)
+{
+       QStringList expList;
+       QString expected;
+       for (int i=0; i<plist.count();i++)
+       {
+               if (checkParCount (plist[i])) 
+               {
+                       resetError();
+                       return true;
+               }
+               expList.append(QString().setNum(plist[i]));
+       }       
+       expected=expList.join(",");     
+       errDescription=QString("Wrong number of parameters: Expected %1, but found %2").arg(expected).arg(paramList.count());
+       return false;
+}
+
+bool Parser::checkParCount (const int &expected)
+{
+       if (paramList.count()!=expected)
+       {
+               errLevel=Aborted;
+               errDescription=QString("Wrong number of parameters: Expected %1, but found %2").arg(expected).arg(paramList.count());
+               return false;
+       } 
+       return true;    
+}
+
+bool Parser::checkParIsInt(const int &index)
+{
+       bool ok;
+       if (index > paramList.count())
+       {
+               errLevel=Aborted;
+               errDescription=QString("Parameter index %1 is outside of parameter list").arg(index);
+               return false;
+       } else
+       {
+               paramList[index].toInt (&ok, 10);
+               if (!ok)
+               {
+                       errLevel=Aborted;
+                       errDescription=QString("Parameter %1 is not an integer").arg(index);
+                       return false;
+               } 
+       }       
+       return true;
+}
+
+bool Parser::checkParIsDouble(const int &index)
+{
+       bool ok;
+       if (index > paramList.count())
+       {
+               errLevel=Aborted;
+               errDescription=QString("Parameter index %1 is outside of parameter list").arg(index);
+               return false;
+       } else
+       {
+               paramList[index].toDouble (&ok);
+               if (!ok)
+               {
+                       errLevel=Aborted;
+                       errDescription=QString("Parameter %1 is not double").arg(index);
+                       return false;
+               } 
+       }       
+       return true;
+}
+
+int Parser::parInt (bool &ok,const uint &index)
+{
+       if (checkParIsInt (index))
+               return paramList[index].toInt (&ok, 10);
+       ok=false;
+       return 0;
+}
+
+QString Parser::parString (bool &ok,const int &index)
+{
+       // return the string at index, this could be also stored in
+       // a variable later
+       QString r;
+       QRegExp re("\"(.*)\"");
+       int pos=re.search (paramList[index]);
+       if (pos>=0)
+               r=re.cap (1);
+       else    
+               r="";
+       ok=true;
+       return r;
+}
+
+bool Parser::parBool (bool &ok,const int &index)
+{
+       // return the bool at index, this could be also stored in
+       // a variable later
+       QString r;
+       ok=true;
+       QString p=paramList[index];
+       if (p=="true" || p=="1")
+               return true;
+       else if (p=="false" || p=="0")
+               return false;
+       ok=false;
+       return ok;
+}
+
+QColor Parser::parColor(bool &ok,const int &index)
+{
+       // return the QColor at index
+       ok=false;
+       QString r;
+       QColor c;
+       QRegExp re("\"(.*)\"");
+       int pos=re.search (paramList[index]);
+       if (pos>=0)
+       {
+               r=re.cap (1);
+               c.setNamedColor(r);
+               ok=c.isValid();
+       }       
+       return c;
+}
+
+double Parser::parDouble (bool &ok,const int &index)
+{
+       if (checkParIsDouble (index))
+               return paramList[index].toDouble (&ok);
+       ok=false;
+       return 0;
+}
+
+void Parser::setScript(const QString &s)
+{
+       script=s;
+}      
+
+QString Parser::getScript()
+{
+       return script;
+}      
+
+void Parser::runScript()
+{
+       current=0;
+}      
+
+bool Parser::next()
+{
+       int start=current;
+       if (current<0) runScript();
+       if (current>=script.length()-1) return false;
+
+       bool inBracket=false;
+       while (true)
+       {
+               //cout <<"current="<<current<< "   start="<<start<<"  length="<<script.length()<<endl;
+
+               // Check if we are inside a string
+               if (script.at(current)=='"')
+               {
+                       if (inBracket)
+                               inBracket=false;
+                       else    
+                               inBracket=true;
+               }
+
+               // Check if we are in a comment
+               if (!inBracket && script.at(current)=='#')
+               {
+                       while (script.at(current)!='\n')
+                       {
+                               current++;
+                               if (current>=script.length()) 
+                                       return false;
+                       }
+                       start=current;
+               }
+
+               // Check for end of atom
+               if (!inBracket && script.at(current)==';')
+               {
+                       atom=script.mid(start,current-start);
+                       current++;
+                       return true;
+               }
+               
+               // Check for end of script
+               if (current==script.length() )
+               {
+                       if (inBracket)
+                       {
+                               setError (Aborted,"Runaway string");
+                               return false;
+                       } else
+                       {
+                               atom=script.mid(start);
+                               return true;
+                       }
+               }
+               current++;
+       }
+}      
+