示例#1
0
static Lexem ParseNumericConstant( const std::string& file_data, std::string::const_iterator& it )
{
	Lexem result;

	result.file_position= it - file_data.begin();

	// Hex
	if( *it == '0' && (it+1) < file_data.end() && *(it+1) == 'x' )
	{
		if( it+2 == file_data.end() || !IsHexDigit(*it) )
			throw LexicalError( it - file_data.begin() );

		result.text+= "0x";
		it+= 2;

		while( it != file_data.end() && IsHexDigit(*it) )
		{
			result.text+= *it;
			it++;
		}
	}
	else
		while( it != file_data.end() && isdigit(*it) )
		{
			result.text+= *it;
			it++;
		}

	if( it != file_data.end() && isalpha(*it) )
		throw LexicalError( it - file_data.begin() );

	result.type= Lexem::Type::NumericConstant;
	return result;
}
示例#2
0
static BinaryOperationsChain ParseBinaryOperatorsChain( const Lexems& lexems, Lexems::const_iterator& it )
{
	BinaryOperationsChain result;

	while( it < lexems.end() )
	{
		BinaryOperationsChain::ComponentWithOperator comp;

		switch (it->type)
		{
		case Lexem::Type::Identifier:
		case Lexem::Type::Scope:
			{
				std::unique_ptr<BinaryOperationsChain::Variable> var( new BinaryOperationsChain::Variable );
				var->name= ParseCombinedName( lexems, it );

				comp.component= std::move(var);
			}
			break;

		case Lexem::Type::BracketLeft:
			{
				it++;
				if( it == lexems.end()) throw LexicalError(lexems.back().file_position);

				std::unique_ptr<BinaryOperationsChain::BracketExpression> subexpr( new BinaryOperationsChain::BracketExpression );
				subexpr->subexpression.reset( new BinaryOperationsChain(ParseBinaryOperatorsChain( lexems, it )) );
				comp.component= std::move(subexpr);

				if( it->type != Lexem::Type::BracketRight ) throw LexicalError( it->file_position);
				it++;
			}
			break;

		case Lexem::Type::NumericConstant:
			{
				std::unique_ptr<BinaryOperationsChain::NumericConstant> num( new BinaryOperationsChain::NumericConstant );
				num->value= it->text;
				it++;

				comp.component= std::move(num);
			}
			break;

		default:
			goto end;
		};

		BinaryOperationsChain::Operator op= ParseBinaryOperator( it );
		comp.op= op;
		result.components.push_back(std::move(comp));

		if( op == BinaryOperationsChain::Operator::NoOperator ) break;
	}
	end:;

	return result;
}
示例#3
0
Token Source::read_chars(size_t number, bool escape)
{
    Info start = this->get_info();
    std::string s;
    char c;
    while(s.size() < number && ! this->eof())
    {
        c = this->current();
        if(escape && c == string::ESCAPE)
        {
            s += c; // ...
            this->consume();
            s += this->current();
        }
        else if(c == 0)
        {
            throw LexicalError(DEBUG_INFO, this, this->get_info(), "EOF found during scanning");
        }
        else
        {
            s += c;
        }
        this->consume();
    }
    return Token(start, this->get_info(), s);
}
示例#4
0
Token Source::read_up_to_delimiters(std::string delimiters, bool escape, bool include_delimiter)
{
    Info start = this->get_info();
    std::string s;
    while(true)
    {
        char c = this->current();
        if(delimiters.find(c) != delimiters.npos)
        {
            if(include_delimiter)
            {
                s += c;
            }
            break;
        }
        else if(escape && c == string::ESCAPE)
        {
            //s += c; // ...
            this->consume();
            s += this->current();
        }
        else if(c == 0)
        {
            throw LexicalError(DEBUG_INFO, this, this->get_info(), "EOF found during scanning");
        }
        else
        {
            s += c;
        }
        this->consume();
    }
    return Token(start, this->get_info(), s);
}
示例#5
0
Token Source::read_up_to_delimiter(std::string substring, bool escape, bool include_delimiter)
{
    Info start = this->get_info();
    std::string s;
    size_t s_pos = 0;
    size_t s_len = substring.size();
    //char s_c;
    char c;
    std::string s_s;
    while(true)
    {
        //s_c = substring[s_pos];
        c = this->current();
        if(escape && c == string::ESCAPE)
        {
            s += c; //...
            this->consume();
            s += this->current();
            s_pos = 0;
        }
        else if(c == substring[s_pos])
        {
            s_s += c;
            ++s_pos;
            if(s_pos == s_len)
            {
                break;
            }
        }
        else if(s_pos > 0)
        {
            s_s.clear();
            s_pos = 0;
            continue;
        }
        else if(c == 0)
        {
            throw LexicalError(DEBUG_INFO, this, this->get_info(), "EOF found during scanning");
        }
        else
        {
            s += c;
        }
        this->consume();
    }
    if(include_delimiter)
    {
        s += s_s;
    }
    return Token(start, this->get_info(), s);
}
示例#6
0
    bool SimpleParser::Parse(const GPSTR_T &source, GPSTR_T &msgOut, bool trimReductions)
    {
      /* This procedure starts the GOLD Parser Engine and handles each of the
      messages it returns. Each time a reduction is made, you can create new
      custom object and reassign the .CurrentReduction property. Otherwise,
      the system will use the Reduction object that was returned.

      The resulting tree will be a pure representation of the language
      and will be ready to implement. */

      ParseMessage response;
      bool done;                      //Controls when we leave the loop
      bool accepted = false;          //Was the parse successful?

      parser_->Open(source);
      parser_->TrimReductions = trimReductions;  //Please read about this feature before enabling

      done = false;
      while (!done)
      {
          response = parser_->Parse();

          switch (response)
          {
              case ParseMessage::LexicalError:
                  //Cannot recognize token
                  msgOut = LexicalError(this, parser_);
                  done = true;
                  break;

              case ParseMessage::SyntaxError:
                  //Expecting a different token
                  msgOut = SyntaxError(this, parser_);
                  done = true;
                  break;

              case ParseMessage::Reduction:
                  parser_->SetCurrentReduction(Reduce(this, parser_->GetCurrentReduction()));
                  break;

              case ParseMessage::Accept:
                  //Accepted!
                  Root = parser_->GetCurrentReduction();    //The root node!
                  done = true;
                  accepted = true;
                  break;

              case ParseMessage::TokenRead:
                  //You don't have to do anything here.
                  break;

              case ParseMessage::InternalError:
                  //INTERNAL ERROR! Something is horribly wrong.
                  msgOut = InternalError(this);
                  done = true;
                  break;

              case ParseMessage::NotLoadedError:
                  //This error occurs if the EGT was not loaded.
                  msgOut = TablesNotLoaded(this);
                  done = true;
                  break;

              case ParseMessage::GroupError:
                  //GROUP ERROR! Unexpected end of file
                  msgOut = Runaway(this);
                  done = true;
                  break;
          }
      } //while

      return accepted;
    }