Пример #1
0
void SchemaParser::loadFile(const QString &file)
{
	if(file!="")
	{
		ifstream input;
		char buf_aux[1025];
		QString str_aux;
		int pos;

		//Open the file for reading
		input.open(file.toStdString().c_str());

		if(!input.is_open())
		{
			str_aux=Exception::getErrorMessage(ERR_FILE_DIR_NOT_ACCESSED).arg(file);
			throw Exception(str_aux, ERR_FILE_DIR_NOT_ACCESSED,__PRETTY_FUNCTION__,__FILE__,__LINE__);
		}

		//Prepares the parser to do new reading
		restartParser();

		//While the input file doesn't reach the end
		while(!input.eof())
		{
			//Get one line from file (until the last char before \n)
			input.getline(buf_aux,1024);
			str_aux=buf_aux;

			/* Since the method getline discards the \n when the line was just a line break
			its needed to treat it in order to not lost it */
			if(str_aux=="") str_aux+=CHR_LINE_END;

			/* Caso a linha inteira esteja comentada (iniciada por um caractere
			de comentário), incrementa o contadore de linhas de comentário. */

			//If the entire line is commented out increases the comment lines counter
			if(str_aux[0]==CHR_COMMENT) comment_count++;

			//Looking for the position of other comment characters for deletion
			pos=str_aux.indexOf(CHR_COMMENT);

			//Removes the characters from the found position
			if(pos >= 0)
				str_aux.remove(pos, str_aux.size());

			if(str_aux!="")
			{
				//Add a line break in case the last character is not
				if(str_aux[str_aux.size()-1]!=CHR_LINE_END)
					str_aux+=CHR_LINE_END;

				//Add the treated line in the buffer
				buffer.push_back(str_aux);
			}
		}

		//Close the file stream
		input.close();
	}
}
Пример #2
0
void XMLParser::readBuffer(void)
{
    QByteArray buffer;
    QString msg, file;
    xmlError *xml_error=nullptr;
    int parser_opt;

    if(!xml_buffer.isEmpty())
    {
        //Inserts the XML declaration
        buffer+=xml_decl;

        //Configures the parser, initially, to not validate the document against the dtd
        parser_opt=( XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOENT );

        //If the dtd declarions is setup
        if(!dtd_decl.isEmpty())
        {
            //Inserts the default software DTD declarion into XML buffer
            buffer+=dtd_decl;

            //Now configures the parser to validate the buffer against the DTD
            parser_opt=(parser_opt | XML_PARSE_DTDLOAD | XML_PARSE_DTDVALID);
        }

        buffer+=xml_buffer;

        //Create an xml document from the buffer
        xml_doc=xmlReadMemory(buffer.data(), buffer.size(),	nullptr, nullptr, parser_opt);

        //In case the document criation fails, gets the last xml parser error
        xml_error=xmlGetLastError();

        //If some error is set
        if(xml_error)
        {
            //Formats the error
            msg=xml_error->message;
            file=xml_error->file;
            if(!file.isEmpty()) file="("+file+")";
            msg.replace("\n"," ");

            //Restarts the parser
            if(xml_doc) restartParser();

            //Raise an exception with the error massege from the parser xml
            throw Exception(QString(Exception::getErrorMessage(ERR_LIBXMLERR))
                            .arg(xml_error->line).arg(xml_error->int2).arg(msg).arg(file),
                            ERR_LIBXMLERR,__PRETTY_FUNCTION__,__FILE__,__LINE__);
        }

        //Gets the referênce to the root element on the document
        root_elem=curr_elem=xmlDocGetRootElement(xml_doc);
    }
}
Пример #3
0
XMLParser::~XMLParser(void)
{
    restartParser();
    xmlCleanupParser();
}
Пример #4
0
QString SchemaParser::getCodeDefinition(const QString &filename, map<QString,QString> &attributes)
{
	QString object_def;

	if(filename!="")
	{
		unsigned end_cnt, if_cnt;
		int if_level, prev_if_level;
		QString atrib, cond, prev_cond, word, meta, str_aux;
		bool error, if_attrib;
		char chr;
		vector<bool> vet_expif, vet_tk_if, vet_tk_then, vet_tk_else;
		map<int, vector<QString> > if_map, else_map;
		vector<QString>::iterator itr, itr_end;
		vector<int> vet_prev_level;
		vector<QString> *vet_aux;

		SchemaParser::filename=filename;
		loadFile(filename);

		//In case the file was successfuly loaded
		if(buffer.size() > 0)
		{
			//Init the control variables
			error=if_attrib=false;
			if_level=-1;
			end_cnt=if_cnt=0;

			while(line < buffer.size())
			{
				chr=buffer[line][column].toAscii();
				switch(chr)
				{
					/* Increments the number of rows causing the parser
			 to get the next line buffer for analysis */
					case CHR_LINE_END:
						line++;
						column=0;
					break;

					case CHR_SPACE:
						//The parser will ignore the spaces that are not within pure texts
						while(buffer[line][column]==CHR_SPACE) column++;
					break;

						//Metacharacter extraction
					case CHR_INI_METACHAR:
						meta=getMetaCharacter();

						//Checks whether the extracted token is valid metacharacter
						if(meta!=TOKEN_META_SP && meta!=TOKEN_META_TB &&
							 meta!=TOKEN_META_BR)
						{
							str_aux=QString(Exception::getErrorMessage(ERR_INV_METACHARACTER))
											.arg(meta).arg(filename).arg(line + comment_count +1).arg(column+1);


							throw Exception(str_aux,ERR_INV_METACHARACTER,__PRETTY_FUNCTION__,__FILE__,__LINE__);
						}
						//Checks whether the metacharacter is part of the  'if' expression (this is an error)
						else if(if_level>=0 && vet_tk_if[if_level] && !vet_tk_then[if_level])
						{
							str_aux=QString(Exception::getErrorMessage(ERR_INVALID_SYNTAX))
											.arg(filename).arg(line + comment_count +1).arg(column+1);

							throw Exception(str_aux,ERR_INVALID_SYNTAX,__PRETTY_FUNCTION__,__FILE__,__LINE__);
						}
						else
						{
							//Converting the metacharacter drawn to the character that represents this
							if(meta==TOKEN_META_SP) chr=CHR_SPACE;
							else if(meta==TOKEN_META_TB) chr=CHR_TABULATION;
							else chr=CHR_LINE_END;

							meta="";
							meta+=chr;

							//If the parser is inside an 'if / else' extracting tokens
							if(if_level>=0)
							{
								/* If the parser is in 'if' section,
									 places the metacharacter on the word map of the current 'if' */
								if(vet_tk_if[if_level] &&
									 vet_tk_then[if_level] &&
									 !vet_tk_else[if_level])
									if_map[if_level].push_back(meta);

								/* If the parser is in 'else' section,
									 places the metacharacter on the word map of the current 'else'*/
								else if(vet_tk_else[if_level])
									else_map[if_level].push_back(meta);
							}
							else
								/* If the parsers is not in a 'if / else', puts the metacharacter
									 in the definition sql */
								object_def+=meta;
						}

					break;

						//Attribute extraction
					case CHR_INI_ATTRIB:
					case CHR_MID_ATTRIB:
					case CHR_END_ATTRIB:
						atrib=getAttribute();

						//Checks if the attribute extracted belongs to the passed list of attributes
						if(attributes.count(atrib)==0)
						{
							if(!ignore_unk_atribs)
							{
								str_aux=QString(Exception::getErrorMessage(ERR_UNK_ATTRIBUTE))
												.arg(atrib).arg(filename).arg((line + comment_count +1)).arg((column+1));
								throw Exception(str_aux,ERR_UNK_ATTRIBUTE,__PRETTY_FUNCTION__,__FILE__,__LINE__);
							}
							else
								attributes[atrib]="";
						}

						//If the parser is inside an 'if / else' extracting tokens
						if(if_level>=0)
						{
							/* If the parser is in the 'if' part of the expression but not yet
								extracted the attribute */
							if(!if_attrib && vet_tk_if[if_level] && !vet_tk_then[if_level])
							{
								//Mark the flag indicating that an attribute of the if / then has been extracted
								if_attrib=true;

								//Checks if the attribute value is empty. If not evaluates as true the conditional expression
								vet_expif.push_back((attributes[atrib]!=""));
							}

							/* If the parser is in the part of the 'if' expression and yet
								extracted the attribute, returns an error because only one attribute
								may appear if expression */
							else if(if_attrib && vet_tk_if[if_level] && !vet_tk_then[if_level])
							{
								str_aux=QString(Exception::getErrorMessage(ERR_INVALID_SYNTAX))
												.arg(filename).arg(line + comment_count +1).arg(column+1);

								throw Exception(str_aux,ERR_INVALID_SYNTAX,__PRETTY_FUNCTION__,__FILE__,__LINE__);
							}
							else
							{
								word=atrib;
								atrib="";
								atrib+=CHR_INI_ATTRIB;
								atrib+=CHR_MID_ATTRIB;
								atrib+=word;
								atrib+=CHR_END_ATTRIB;

								//If the parser is in the 'if' section
								if(vet_tk_if[if_level] &&
									 vet_tk_then[if_level] &&
									 !vet_tk_else[if_level])
									//Inserts the attribute value in the map of the words of current the 'if' section
									if_map[if_level].push_back(atrib);
								else if(vet_tk_else[if_level])
									//Inserts the attribute value in the map of the words of current the 'else' section
									else_map[if_level].push_back(atrib);
							}
						}
						else
						{
							if(attributes[atrib]=="")
							{
								str_aux=QString(Exception::getErrorMessage(ERR_UNDEF_ATTRIB_VALUE))
												.arg(atrib).arg(filename).arg(line + comment_count +1).arg(column+1);

								throw Exception(str_aux,ERR_UNDEF_ATTRIB_VALUE,__PRETTY_FUNCTION__,__FILE__,__LINE__);
							}

							/* If the parser is not in an if / else, concatenates the value of the attribute
								directly in definition in sql */
							object_def+=attributes[atrib];
						}
					break;

						//Conditional instruction extraction
					case CHR_INI_CONDITIONAL:
						prev_cond=cond;
						cond=getConditional();

						//Checks whether the extracted token is a valid conditional
						if(cond!=TOKEN_IF && cond!=TOKEN_ELSE &&
							 cond!=TOKEN_THEN && cond!=TOKEN_END)
						{
							str_aux=QString(Exception::getErrorMessage(ERR_INV_CONDITIONAL))
											.arg(cond).arg(filename).arg(line + comment_count +1).arg(column+1);
							throw Exception(str_aux,ERR_INV_CONDITIONAL,__PRETTY_FUNCTION__,__FILE__,__LINE__);
						}
						else
						{
							//If the toke is an 'if'
							if(cond==TOKEN_IF)
							{
								/* Inserts the value of the current 'if' level  in the previous 'if' levels vector.
								 This vector is used to know which 'if' the parser was in before entering current if */
								vet_prev_level.push_back(if_level);

								/* Mark the flags indicating that an  'if' was found and a
								 'then' and 'else' have not been found yet */
								vet_tk_if.push_back(true);
								vet_tk_then.push_back(false);
								vet_tk_else.push_back(false);

								//Defines the current if level as the size of list 'if' tokens found  -1
								if_level=(vet_tk_if.size()-1);

								//Increases the number of found 'if's
								if_cnt++;
							}
							//If the parser is in 'if / else' and one 'then' token is found
							else if(cond==TOKEN_THEN && if_level>=0)
							{
								//Marks the then thoke flag of the current 'if'
								vet_tk_then[if_level]=true;

								/* Clears the  attribute extracted flag from the 'if - then',
									 so that the parser does not generate an error when it encounters another
									 'if - then' with an attribute still unextracted */
								if_attrib=false;
							}
							//If the parser is in 'if / else' and a 'else' token is found
							else if(cond==TOKEN_ELSE && if_level>=0)
								//Mark the  o flag do token else do if atual
								vet_tk_else[if_level]=true;
							//Case the parser is in 'if/else' and a 'end' token was found
							else if(cond==TOKEN_END && if_level>=0)
							{
								//Increments the number of 'end' tokes found
								end_cnt++;

								//Get the level of the previous 'if' where the parser was
								prev_if_level=vet_prev_level[if_level];

								//In case the current 'if' be internal (nested) (if_level > 0)
								if(if_level > 0)
								{
									//In case the current 'if' doesn't in the 'else' section of the above 'if' (previous if level)
									if(!vet_tk_else[prev_if_level])
										//Get the extracted word vector on the above 'if'
										vet_aux=&if_map[prev_if_level];
									else
										//Get the extracted word vector on the above 'else'
										vet_aux=&else_map[prev_if_level];
								}
								else
									vet_aux=NULL;

								/* Initializes the iterators to scan
									 the auxiliary vector if necessary */
								itr=itr_end=if_map[0].end();

								/* In case the expression of the current 'if' has the value true
									 then the parser will scan the list of words on the 'if' part of the
									 current 'if' */
								if(vet_expif[if_level])
								{
									itr=if_map[if_level].begin();
									itr_end=if_map[if_level].end();
								}
								/* Caso a parte else do if atual exista
									 então o parser varrerá a lista de palavras da parte else
									 do if atual */

								/* If there is a 'else' part on the current 'if'
									 then the parser will scan the list of words on the 'else' part */
								else if(else_map.count(if_level)>0)
								{
									itr=else_map[if_level].begin();
									itr_end=else_map[if_level].end();
								}

								/* This iteration scans the list of words selected above
									 inserting them in 'if' part  of the 'if' or 'else' superior to current.
									 This is done so that only the words extracted based on
									 ifs expressions of the buffer are embedded in defining sql */
								while(itr!=itr_end)
								{
									//If the auxiliary vector is allocated, inserts the word on above 'if / else'
									if(vet_aux)
										vet_aux->push_back((*itr));
									else
									{
										word=(*itr);

										//Check if the work is not an attribute
										if(word[0]==CHR_INI_ATTRIB)
										{
											/* If its an attribute, extracts the name and checks if the same
											has empty value */
											atrib=word.mid(2,word.size()-3);
											word=attributes[atrib];

											//If the attribute has no value set raises an exception
											if(word=="")
											{
												str_aux=QString(Exception::getErrorMessage(ERR_UNDEF_ATTRIB_VALUE))
																.arg(atrib).arg(filename).arg(line + comment_count +1).arg(column+1);
												throw Exception(str_aux,ERR_UNDEF_ATTRIB_VALUE,__PRETTY_FUNCTION__,__FILE__,__LINE__);
											}
										}

										//Else, insert the work directly on the object definition
										object_def+=word;
									}
									itr++;
								}

								//Case the current if is nested (internal)
								if(if_level > 0)
									//Causes the parser to return to the earlier 'if'
									if_level=prev_if_level;

								/* In case the 'if' be the uppermost (level 0) indicates that all
									 the if's  has already been checked, so the parser will clear the
									 used auxiliary structures*/
								else
								{
									if_map.clear();
									else_map.clear();
									vet_tk_if.clear();
									vet_tk_then.clear();
									vet_tk_else.clear();
									vet_expif.clear();
									vet_prev_level.clear();

									//Resets the ifs levels
									if_level=prev_if_level=-1;
								}
							}
							else
								error=true;

							if(!error)
							{
								/* Verifying that the conditional words appear in a valid  order if not
								 the parser generates an error. Correct order means IF before THEN,
								 ELSE after IF and before END */
								if((prev_cond==TOKEN_IF && cond!=TOKEN_THEN) ||
									 (prev_cond==TOKEN_ELSE && cond!=TOKEN_IF && cond!=TOKEN_END) ||
									 (prev_cond==TOKEN_THEN && cond==TOKEN_THEN))
									error=true;
							}

							if(error)
							{
								str_aux=QString(Exception::getErrorMessage(ERR_INVALID_SYNTAX))
												.arg(filename).arg(line + comment_count +1).arg(column+1);
								throw Exception(str_aux,ERR_INVALID_SYNTAX,__PRETTY_FUNCTION__,__FILE__,__LINE__);
							}
						}
					break;

						//Extraction of pure text or simple words
					default:
						if(chr==CHR_INI_PURETEXT ||
							 chr==CHR_END_PURETEXT)
							word=getPureText();
						else
							word=getWord();

						//Case the parser is in 'if/else'
						if(if_level>=0)
						{
							/* In case the word/text be inside 'if' expression, the parser returns an error
							 because only an attribute must be on the 'if' expression  */
							if(vet_tk_if[if_level] && !vet_tk_then[if_level])
							{
								str_aux=QString(Exception::getErrorMessage(ERR_INVALID_SYNTAX))
												.arg(filename).arg(line + comment_count +1).arg(column+1);
								throw Exception(str_aux,ERR_INVALID_SYNTAX,__PRETTY_FUNCTION__,__FILE__,__LINE__);
							}
							//Case the parser is in 'if' section
							else if(vet_tk_if[if_level] &&
											vet_tk_then[if_level] &&
											!vet_tk_else[if_level])
								//Inserts the word on the words map extracted on 'if' section
								if_map[if_level].push_back(word);
							else if(vet_tk_else[if_level])
								//Inserts the word on the words map extracted on 'else' section
								else_map[if_level].push_back(word);
						}
						else
							//Case the parser is not in 'if/else' concatenates the word/text directly on the object definition
							object_def+=word;
					break;
				}
			}

			/* If has more 'if' toknes than  'end' tokens, this indicates that some 'if' in code
			was not closed thus the parser returns an error */
			if(if_cnt!=end_cnt)
			{
				str_aux=QString(Exception::getErrorMessage(ERR_INVALID_SYNTAX))
								.arg(filename).arg(line + comment_count +1).arg(column+1);
				throw Exception(str_aux,ERR_INVALID_SYNTAX,__PRETTY_FUNCTION__,__FILE__,__LINE__);
			}
		}
	}

	restartParser();
	ignore_unk_atribs=false;
	return(object_def);
}