parser.cpp
author insilmaril
Tue, 09 Mar 2010 08:28:49 +0000
changeset 830 b5537d245165
parent 816 3086ee01554a
permissions -rw-r--r--
Minor bugfix: editSortBack is no toggle action
     1 #include "parser.h"
     2 
     3 #include <QRegExp>
     4 #include <iostream>
     5 
     6 using namespace std;
     7 
     8 Parser::Parser()
     9 {
    10 	initParser();
    11 }
    12 
    13 void Parser::initParser()
    14 {
    15 	initAtom();
    16 	current=-1;
    17 }
    18 
    19 void Parser::initAtom()
    20 {
    21 	atom="";
    22 	com="";
    23 	paramList.clear();
    24 	resetError();
    25 }
    26 
    27 void Parser::parseAtom (QString s)
    28 {
    29 	initAtom();
    30 	atom=s;
    31 	QRegExp re;
    32 	int pos;
    33 
    34 	// Strip WS at beginning
    35 	re.setPattern ("\\w");
    36 	re.setMinimal (true);
    37 	pos=re.search (atom);
    38 	if (pos>=0)
    39 		s=s.right(s.length()-pos);
    40 
    41 	// Get command
    42 	re.setPattern ("\\b(.*)(\\s|\\()");
    43 	pos=re.search (s);
    44 	if (pos>=0)
    45 		com=re.cap(1);
    46 
    47 	// Get parameters
    48 	paramList.clear();
    49 	re.setPattern ("\\((.*)\\)");
    50 	pos=re.search (s);
    51 	//cout << "  s="<<qPrintable(s)<<endl;
    52 	//cout << "com="<<qPrintable(com)<<"  pos="<<pos<<endl<<endl;
    53 	if (pos>=0)
    54 	{
    55 		QString s=re.cap(1);
    56 		QString a;
    57 		bool inquote=false;
    58 		pos=0;
    59 		if (!s.isEmpty())
    60 		{
    61 			while (pos<s.length())
    62 			{
    63 				if (s.at(pos)=='\"') 
    64 				{
    65 					if (inquote)
    66 						inquote=false;
    67 					else	
    68 						inquote=true;
    69 				}
    70 
    71 				if (s.at(pos)==',' && !inquote)
    72 				{
    73 					a=s.left(pos);
    74 					paramList.append(a);
    75 					s=s.right(s.length()-pos-1);
    76 					pos=0;
    77 				} else
    78 					pos++;
    79 				
    80 			}
    81 			paramList.append (s);
    82 		}	
    83 	}	
    84 }
    85 
    86 QString Parser::getAtom()
    87 {
    88 	return atom;
    89 }
    90 
    91 QString Parser::getCommand()
    92 {
    93 	return com;
    94 }
    95 
    96 QStringList Parser::getParameters()
    97 {
    98 	return paramList;
    99 }
   100 
   101 int Parser::parCount()
   102 {
   103 	return paramList.count();
   104 }
   105 
   106 
   107 QString Parser::errorMessage()
   108 {
   109 	QString l;
   110 	switch (errLevel)
   111 	{
   112 		case NoError: l="No Error";
   113 		case Warning: l="Warning";
   114 		case Aborted: l="Aborted";
   115 	}
   116 	return QString ("Error Level: %1\n    Command: %2\nDescription: %3")
   117 		.arg(l).arg(com).arg(errDescription);
   118 }
   119 
   120 QString Parser::errorDescription()
   121 {
   122 	return errDescription;
   123 }
   124 
   125 ErrorLevel Parser::errorLevel()
   126 {
   127 	return errLevel;
   128 }
   129 
   130 void Parser::setError(ErrorLevel level, const QString &description)
   131 {
   132 	errDescription=description;
   133 	errLevel=level;
   134 }
   135 
   136 void Parser::resetError ()
   137 {
   138 	errMessage="";
   139 	errDescription="";
   140 	errLevel=NoError;
   141 }
   142 
   143 
   144 bool Parser::checkParCount (QList <int> plist)
   145 {
   146 	QStringList expList;
   147 	QString expected;
   148 	for (int i=0; i<plist.count();i++)
   149 	{
   150 		if (checkParCount (plist[i])) 
   151 		{
   152 			resetError();
   153 			return true;
   154 		}
   155 		expList.append(QString().setNum(plist[i]));
   156 	}	
   157 	expected=expList.join(",");	
   158 	errDescription=QString("Wrong number of parameters: Expected %1, but found %2").arg(expected).arg(paramList.count());
   159 	return false;
   160 }
   161 
   162 bool Parser::checkParCount (const int &expected)
   163 {
   164 	if (paramList.count()!=expected)
   165 	{
   166 		errLevel=Aborted;
   167 		errDescription=QString("Wrong number of parameters: Expected %1, but found %2").arg(expected).arg(paramList.count());
   168 		return false;
   169 	} 
   170 	return true;	
   171 }
   172 
   173 bool Parser::checkParIsInt(const int &index)
   174 {
   175 	bool ok;
   176 	if (index > paramList.count())
   177 	{
   178 		errLevel=Aborted;
   179 		errDescription=QString("Parameter index %1 is outside of parameter list").arg(index);
   180 		return false;
   181 	} else
   182 	{
   183 		paramList[index].toInt (&ok, 10);
   184 		if (!ok)
   185 		{
   186 			errLevel=Aborted;
   187 			errDescription=QString("Parameter %1 is not an integer").arg(index);
   188 			return false;
   189 		} 
   190 	}	
   191 	return true;
   192 }
   193 
   194 bool Parser::checkParIsDouble(const int &index)
   195 {
   196 	bool ok;
   197 	if (index > paramList.count())
   198 	{
   199 		errLevel=Aborted;
   200 		errDescription=QString("Parameter index %1 is outside of parameter list").arg(index);
   201 		return false;
   202 	} else
   203 	{
   204 		paramList[index].toDouble (&ok);
   205 		if (!ok)
   206 		{
   207 			errLevel=Aborted;
   208 			errDescription=QString("Parameter %1 is not double").arg(index);
   209 			return false;
   210 		} 
   211 	}	
   212 	return true;
   213 }
   214 
   215 int Parser::parInt (bool &ok,const uint &index)
   216 {
   217 	if (checkParIsInt (index))
   218 		return paramList[index].toInt (&ok, 10);
   219 	ok=false;
   220 	return 0;
   221 }
   222 
   223 QString Parser::parString (bool &ok,const int &index)
   224 {
   225 	// return the string at index, this could be also stored in
   226 	// a variable later
   227 	QString r;
   228 	QRegExp re("\"(.*)\"");
   229 	int pos=re.search (paramList[index]);
   230 	if (pos>=0)
   231 		r=re.cap (1);
   232 	else	
   233 		r="";
   234 	ok=true;
   235 	return r;
   236 }
   237 
   238 bool Parser::parBool (bool &ok,const int &index)
   239 {
   240 	// return the bool at index, this could be also stored in
   241 	// a variable later
   242 	QString r;
   243 	ok=true;
   244 	QString p=paramList[index];
   245 	if (p=="true" || p=="1")
   246 		return true;
   247 	else if	(p=="false" || p=="0")
   248 		return false;
   249 	ok=false;
   250 	return ok;
   251 }
   252 
   253 QColor Parser::parColor(bool &ok,const int &index)
   254 {
   255 	// return the QColor at index
   256 	ok=false;
   257 	QString r;
   258 	QColor c;
   259 	QRegExp re("\"(.*)\"");
   260 	int pos=re.search (paramList[index]);
   261 	if (pos>=0)
   262 	{
   263 		r=re.cap (1);
   264 		c.setNamedColor(r);
   265 		ok=c.isValid();
   266 	}	
   267 	return c;
   268 }
   269 
   270 double Parser::parDouble (bool &ok,const int &index)
   271 {
   272 	if (checkParIsDouble (index))
   273 		return paramList[index].toDouble (&ok);
   274 	ok=false;
   275 	return 0;
   276 }
   277 
   278 void Parser::setScript(const QString &s)
   279 {
   280 	script=s;
   281 }	
   282 
   283 QString Parser::getScript()
   284 {
   285 	return script;
   286 }	
   287 
   288 void Parser::runScript()
   289 {
   290 	current=0;
   291 }	
   292 
   293 bool Parser::next()
   294 {
   295 	int start=current;
   296 	if (current<0) runScript();
   297 	if (current+1>=script.length()) return false;
   298 
   299 	bool inBracket=false;
   300 	while (true)
   301 	{
   302 		//cout <<"current="<<current<< "   start="<<start<<"  length="<<script.length()<<endl;
   303 
   304 		// Check if we are inside a string
   305 		if (script.at(current)=='"')
   306 		{
   307 			if (inBracket)
   308 				inBracket=false;
   309 			else	
   310 				inBracket=true;
   311 		}
   312 
   313 		// Check if we are in a comment
   314 		if (!inBracket && script.at(current)=='#')
   315 		{
   316 			while (script.at(current)!='\n')
   317 			{
   318 				current++;
   319 				if (current+1>=script.length()) 
   320 					return false;
   321 			}
   322 			start=current;
   323 		}
   324 
   325 		// Check for end of atom
   326 		if (!inBracket && script.at(current)==';')
   327 		{
   328 			atom=script.mid(start,current-start);
   329 			current++;
   330 			return true;
   331 		}
   332 		
   333 		// Check for end of script
   334 		if (current+1>=script.length() )
   335 		{
   336 			if (inBracket)
   337 			{
   338 				setError (Aborted,"Runaway string");
   339 				return false;
   340 			} else
   341 			{
   342 				atom=script.mid(start);
   343 				return true;
   344 			}
   345 		}
   346 		current++;
   347 	}
   348 }	
   349