예제 #1
0
파일: par.c 프로젝트: ordahan/20465-11
/* API Functions */
eParBalanceLine get_par_balance_in_line(char* szLine,
										unsigned int nLineLength,
										int* io_pCurlyBalance)
{
	eParBalanceLine eBalanced = E_PAR_LINE_BALANCED;
	char arrPars[MAX_LINE_LENGTH];
	int nParDepth = -1;
	int i = 0;
	int nCurrCharIndex = 0;
	int fIgnore = 0; /* When we are in the middle of a string, ignore chars */
	int nCurlyBalance = 0;

	/* Make sure the line's length is ok */
	if (nLineLength > MAX_LINE_LENGTH)
	{
		return E_PAR_LINE_ERROR;
	}
	else if (nLineLength == 0)
	{
		return E_PAR_LINE_BALANCED;
	}

	/* Go over the entire line and check for balancing */
	for (i = nCurrCharIndex; (i < MAX_LINE_LENGTH) && (i < nLineLength); ++i)
	{
		/* Set the ignore flag as needed */
		fIgnore = toggle_ignore(szLine[i]);

		/* Not in ignore mode */
		if (!(fIgnore == 1))
		{
			/* Check for parenthesis */
			switch (szLine[i])
			{
			/* An opening parenthesis */
			case '{':
			{
				/* Count curly separately */
				nCurlyBalance++;
				/* Continue to the rest of the handling normally */
			}
			case '(':
			case '[':
			{
				/* Don't count these as valid if we already short of parenthesis */
				if (nParDepth >= -1)
				{
					nParDepth = opening_parenthesis(szLine[i], arrPars, nParDepth);
				}
				break;
			}
			/* A closing parenthesis */
			case '}':
			{
				/* Count curly separately */
				nCurlyBalance--;
				/* Continue to the rest of the handling normally */
			}
			case ')':
			case ']':
			{
				nParDepth = closing_parenthesis(szLine[i], arrPars, nParDepth);
				break;
			}
			default:
				break;
			}
		}
	}

	/* Line is unbalanced */
	if (nParDepth != -1)
	{
		eBalanced = E_PAR_LINE_NOT_BALANCED;
	}

	/* Curly braces not balanced */
	if (nCurlyBalance != 0)
	{
		eBalanced = E_PAR_LINE_NOT_BALANCED_CURLY;
		*io_pCurlyBalance += nCurlyBalance;
	}

	return eBalanced;
}
예제 #2
0
	/*! \param bp The balanced parentheses sequence for that the pioneers should be calculated.
	 *  \param block_size Size of the blocks for which the pioneers should be calculated.
	 *  \param pioneer_bitmap Reference to the resulting bit_vector.
	 *  \par Time complexity
	 *       \f$ \Order{n} \f$, where \f$ n=\f$bp.size()  
	 *  \par Space complexity
	 *       \f$ \Order{2n + n} \f$ bits: \f$n\f$ bits for input, \f$n\f$ bits for output, and \f$n\f$ bits for a succinct stack.
	 *  \pre The parentheses sequence represented by bp has to be balanced.
	 */
	static ::libmaus::bitio::IndexedBitVector::unique_ptr_type calculatePioneerBitVector(::libmaus::bitio::BitVector const & bp, uint64_t const block_size)
	{
		::libmaus::bitio::IndexedBitVector::unique_ptr_type Ppioneer_bitmap(new ::libmaus::bitio::IndexedBitVector(bp.size()));
		::libmaus::bitio::IndexedBitVector & pioneer_bitmap = *Ppioneer_bitmap;

		IncreasingStack opening_parenthesis(bp.size());

		uint64_t cur_pioneer_block = 0;
	 	uint64_t last_start = 0;
	 	uint64_t last_j = 0;
	 	uint64_t cur_block=0;
	 	uint64_t first_index_in_block=0;
	 	
	 	// calculate positions of findclose and findopen pioneers
		for(uint64_t j=0, new_block=block_size; j < bp.size(); ++j, --new_block)
		{
			if( !(new_block) )
			{
				cur_pioneer_block = j/block_size; 
				++cur_block;
				first_index_in_block = j;
				new_block = block_size;
			}

			// opening parenthesis
			if( bp[j] )
			{ 
				/*j < bp.size() is not neccecssary as the last parenthesis is always a closing one*/
				/* if closing par immediately follows opening, skip both and carry on */
				if( new_block>1 and !bp[j+1] )
				{
					++j;
					--new_block;
				}
				/* otherwise push opening par */
				else
				{
					opening_parenthesis.push(j);
				}
			}
			else
			{
				uint64_t const start = opening_parenthesis.top();
				opening_parenthesis.pop();
				// if start is not in this block (i.e. far parenthesis)
				if( start < first_index_in_block )
				{
					// same block as previous pioneer
					if( (start/block_size)==cur_pioneer_block  )
					{
						// erase previous pioneer
						pioneer_bitmap[last_start] = false;
						pioneer_bitmap[last_j] = false;
					}
					// set this pioneer
					pioneer_bitmap[start] = true;
					pioneer_bitmap[j] = true;
					cur_pioneer_block = start/block_size;
					last_start = start;
					last_j = j;
				}
			}
		}
		
		pioneer_bitmap.setupIndex();
		
		return UNIQUE_PTR_MOVE(Ppioneer_bitmap);
	}