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