parser.cpp
author insilmaril
Tue, 19 Jun 2007 14:20:29 +0000
changeset 513 5f576e56ad99
parent 447 72afe12da1c8
child 514 497fab7d1404
permissions -rw-r--r--
Exports can (partly) be scripted
     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="<<s.ascii()<<endl;
    52 	//cout << "com="<<com.ascii()<<"  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::paramCount()
   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::checkParamCount (QList <int> plist)
   145 {
   146 	QStringList expList;
   147 	QString expected;
   148 	for (int i=0; i<plist.count();i++)
   149 	{
   150 		if (checkParamCount (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::checkParamCount (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::checkParamIsInt(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 int Parser::parInt (bool &ok,const uint &index)
   195 {
   196 	if (checkParamIsInt (index))
   197 		return paramList[index].toInt (&ok, 10);
   198 	ok=false;
   199 	return 0;
   200 }
   201 
   202 QString Parser::parString (bool &ok,const int &index)
   203 {
   204 	// return the string at index, this could be also stored in
   205 	// a variable later
   206 	QString r;
   207 	QRegExp re("\"(.*)\"");
   208 	int pos=re.search (paramList[index]);
   209 	if (pos>=0)
   210 		r=re.cap (1);
   211 	else	
   212 		r="";
   213 	ok=true;
   214 	return r;
   215 }
   216 
   217 bool Parser::parBool (bool &ok,const int &index)
   218 {
   219 	// return the bool at index, this could be also stored in
   220 	// a variable later
   221 	QString r;
   222 	ok=true;
   223 	QString p=paramList[index];
   224 	if (p=="true" || p=="1")
   225 		return true;
   226 	else if	(p=="false" || p=="0")
   227 		return false;
   228 	ok=false;
   229 	return ok;
   230 }
   231 
   232 QColor Parser::parColor(bool &ok,const int &index)
   233 {
   234 	// return the QColor at index
   235 	ok=false;
   236 	QString r;
   237 	QColor c;
   238 	QRegExp re("\"(.*)\"");
   239 	int pos=re.search (paramList[index]);
   240 	if (pos>=0)
   241 	{
   242 		r=re.cap (1);
   243 		c.setNamedColor(r);
   244 		ok=c.isValid();
   245 	}	
   246 	return c;
   247 }
   248 
   249 void Parser::setScript(const QString &s)
   250 {
   251 	script=s;
   252 }	
   253 
   254 QString Parser::getScript()
   255 {
   256 	return script;
   257 }	
   258 
   259 void Parser::runScript()
   260 {
   261 	current=0;
   262 }	
   263 
   264 bool Parser::next()
   265 {
   266 	int start=current;
   267 	if (current<0) runScript();
   268 	if (current>=script.length()-1) return false;
   269 
   270 	bool inBracket=false;
   271 	while (true)
   272 	{
   273 		//cout <<"current="<<current<< "   start="<<start<<"  length="<<script.length()<<endl;
   274 
   275 		// Check if we are inside a string
   276 		if (script.at(current)=='"')
   277 		{
   278 			if (inBracket)
   279 				inBracket=false;
   280 			else	
   281 				inBracket=true;
   282 		}
   283 
   284 		// Check if we are in a comment
   285 		if (!inBracket && script.at(current)=='#')
   286 		{
   287 			while (script.at(current)!='\n')
   288 			{
   289 				current++;
   290 				if (current>=script.length()) 
   291 					return false;
   292 			}
   293 			start=current;
   294 		}
   295 
   296 		// Check for end of atom
   297 		if (!inBracket && script.at(current)==';')
   298 		{
   299 			atom=script.mid(start,current-start);
   300 			current++;
   301 			return true;
   302 		}
   303 		
   304 		// Check for end of script
   305 		if (current==script.length() )
   306 		{
   307 			if (inBracket)
   308 			{
   309 				setError (Aborted,"Runaway string");
   310 				return false;
   311 			} else
   312 			{
   313 				atom=script.mid(start);
   314 				return true;
   315 			}
   316 		}
   317 		current++;
   318 	}
   319 }	
   320